CTF中智能合约部署交互基础

0x01 前言

  • Solidity在以太坊中是编写智能合约最受欢迎的语言,一般的CTF竞赛中的智能合约方向的题目都是以solidity语言编写的智能合约。
  • 为什么写这一篇文章,主要是因为在接触智能合约类题目的时候,题目是以提前编写好的代码逻辑存在缺陷或者合约本身存在的问题为考点的,其实题目对于新手而言,难点主要在于solidity语法的陌生,以及完全无法着手智能合约,无法与之交互。所以在接下来的文章中,着重介绍如何进行智能合约的交互。

0x02 Solidity语言&CTF中基础Solidity合约分析

  • 在线编译器 http://remix.ethereum.org/
  • Solidity它的语法与Javascript相似,是一种面向对象的语言。文件后缀名为.sol
  • 基础代码结构
pragma solidity ^0.4.23;

contract Test {  
  mapping (address => uint) balances;
  
  constructor() public {
    balances[tx.origin] = 0;
  }
  event FLAG(string b64email, string slogan);
  
  function getbalance() public constant returns (uint){
      return balances[tx.origin];
  }
  function AddBalance(uint f) public {
    if(f==1){
        balances[tx.origin]++;
    }
  }
  function CaptureTheFlag(string b64email) public{
    require (balances[tx.origin]>0);
    emit FLAG(b64email, "you will get flag!");
  }

}

分析如下

  • 明确solidity语言的版本号
pragma solidity ^0.4.23;
  • 定义一个合约,内部有不同的方法和属性
contract Test {
  ………………
}
  • 更新我们的 balances映射,这是一个余额变量,该变量里面存储了所有拥有代币的地址的余额
mapping (address => uint) balances;
  • 这是一个构造函数,其中tx.origin是Solidity的一个全局变量,它遍历整个调用栈并返回最初发送调用(或事务)的帐户的地址,实现给账户余额赋初始值为0
 constructor() public {
    balances[tx.origin] = 0;
 }
  • 发送flag的合约,邮件发送脚本需部署在服务器
event FLAG(string b64email, string slogan);

其中邮箱发送脚本编写建议参考博客https://www.cnblogs.com/KRDecad3/p/10798383.html

  • 获取账户当前余额
  function getbalance() public constant returns (uint){
      return balances[tx.origin];
  }
  • 为账户增加余额
 function AddBalance(uint f) public {
    if(f==1){
        balances[tx.origin]++;
    }
  }

一般CTF中智能合约题目,都是当发送调用(或事务)的帐户的地址满足一定条件时,然后允许发送flag到指定邮箱。这边就是进行一个简单的为账户余额+1的方法,实现交互,传入f为1即可为余额+1。

  • 判断余额是否大于0,若大于0则调用FLAG方法发送flag
  function CaptureTheFlag(string b64email) public{
    require (balances[tx.origin]>0);
    emit FLAG(b64email, "you will get flag!");
  }
  • 更多solidity语法推荐博客https://www.jianshu.com/p/70aecda3212e

0x03 使用Remix IDE进行合约部署和交互

  • 在线编译器 http://remix.ethereum.org/

合约部署

  • 新建.sol文件

  • 编译.sol文件

编译成功后会显示绿色的勾表示编译成功,如果编译失败可以看编译详细,查看错误原因

  • 部署合约

Environment 选择Injected Web3

Account如果没有的话需要安装MetaMask钱包插件

如果已安装并且登陆的话,在选择Injected Web3时会自动请求连接到你的MetaMask钱包里的账号。

点击Deploy部署合约

  • 部署成功

在MetaMask钱包里面可以看到历史纪录中合约部署成功

合约地址可以在Remix IDE中的Deployed Contracts找到我们成功部署的合约,点击Copy就可以复制合约地址,地址为0x3eCC14397D0413e29b83653691d8614519eA3394。

查询合约地址详细信息的网址为 https://ropsten.etherscan.io/

可以通过该网址查到我们已部署的合约地址产生的记录,当前为部署合约时产生的记录。

合约交互

  • 要和一个已有合约进行交互,必须至少在合约的.sol文件的声明函数原型,然后成功编译。当然一般题目都会给.sol文件,只需要直接编译即可
  • 加载合约

在At Address中填入目的合约的地址,点击At Address加载合约

  • 进行交互

点击getbalance可以看到当前余额为0

调用AddBalance传入1后,等待合约交互成功,然后getbalance发现我们的余额已经实现+1了。

最后将我们的邮箱的base64编码后的值输入,调用合约中CaptureTheFlag方法,等待合约交互成功。

通过查合约地址记录,成功调用到发送flag的合约方法了。到邮箱中查最新的邮件即可。

你可能感兴趣的:(CTF,区块链)