合约流程

编辑合约

你可以基于任何支持solidity的编辑器编写合约。下述将基于remix在线编辑器为例,进行说明。注意使用与合约版本一致的编译器。

为了叙述方便,我们使用如下的简单合约示例:

pragma solidity ^0.4.24;

contract SimpleStorage {
    uint storedData;

    function set(uint x) public {
        storedData = x;
    }

    function get() public view returns (uint) {
        return storedData;
    }
}

编译合约

编写好合约后,可以使用remix的compile功能编译合约,检查合约中可能存在的语法错误。 在Using the contract simulator小节中介绍了如何使用remix获得字节码。

在remix界面中,点击右侧的Run,Environment选择JavaScript VM,可以看到有默认的账户,gas limit, 下方即为我们编辑的合约名称SimpleStorage。点击Deploy可以测试合约的部署并得到字节码。

在remix中间panel的底部有日志窗口,显示部署合约的结果。展开对应的日志内容,可以看到 status,transaction hash等信息。其中的input内容即为该合约对应的字节码。

上述示例合约对应的字节码为:

0x608060405234801561001057600080fd5b5060df8061001f6000396000f3006080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146078575b600080fd5b348015605957600080fd5b5060766004803603810190808035906020019092919050505060a0565b005b348015608357600080fd5b50608a60aa565b6040518082815260200191505060405180910390f35b8060008190555050565b600080549050905600a165627a7a723058208df15a24cad7025968f08e277ea08a607527ac4c4dc9d8ef22c5f1149ea8160d0029

部署合约

有了字节码之后,可以使用seele client工具部署合约。 你可以在seele release中找到相应平台下的软件包。 注意,部署合约与发送交易一样,你需要运行相应的Seele node程序。

本地测试环境

为保障提交到Seele主网的合约是可用的,建议先在本地运行Seele私链节点, 并基于私链进行合约部署和调用测试。

主网环境

本地测试环境通过后,你可以按照私链部署合约的步骤,将合约部署到Seele主网上。 唯一的不同是,你需要运行一个主网的Seele node程序,并保持和Seele主网的数据同步。

通过client工具部署合约

  • 准备一个Seele账户,并确保有足够的余额部署合约。

    这里我们使用分片1的账户0x987f6215c30f1505e0d42769c5472b410d6bf961,并且保存了账户keystore文件

  • 使用sendtx命令部署合约

./client sendtx --amount 0 --from 0x987f6215c30f1505e0d42769c5472b410d6bf961.keystore --payload 0x608060405234801561001057600080fd5b5060ec8061001f6000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146085575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060ad565b005b348015609057600080fd5b50609760b7565b6040518082815260200191505060405180910390f35b8060008190555050565b6000805490509056fea165627a7a7230582045fa1cc38960a931a2b1cf070ffa20bf25683c97838b5f32de5f37a7d6f5568d0029 --gas 100000

sendtx参数amount 为交易金额(单位Fan),对于合约部署通常可以设置为0;from为发送交易账户对应的keystore文件; payload为合约字节码;gas为该笔交易所需最小gas值(默认为20000)。上述命令执行结果如下:

account: 0x987f6215c30f1505e0d42769c5472b410d6bf961, transaction nonce: 0
transaction sent successfully
{
    "Hash": "0x80cb46ef3e3350e5c681397444f2b180624a9c1d534927a12e78cd689ef022fe",
    "Data": {
        "Type": 0,
        "From": "0x987f6215c30f1505e0d42769c5472b410d6bf961",
        "To": "0x0000000000000000000000000000000000000000",
        "Amount": 0,
        "AccountNonce": 0,
        "GasPrice": 10,
        "GasLimit": 200000,
        "Timestamp": 0,
        "Payload": "0x608060405234801561001057600080fd5b5060ec8061001f6000396000f3fe6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463fffffff16806360fe47b114604e5780636d4ce63c146085575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060ad565b005b348015609057600080fd550609760b7565b6040518082815260200191505060405180910390f35b8060008190555050565b6000805490509056fea165627a7a7230582045fa1cc38960a931a2b1cf070ffa20bf25683c97838b5f32de5f37a7d6f5568d0029"
    },
    "Signature": {
        "Sig": "KHi0wZMIeH4SIDtD0hLvDJp++I3H6C7HpFz5H9AEDbIxUDFydVbif9jQtXd9zeDlNfOdCG2x2QwijGVqlFjItQE="
    }
}

根据交易Hash查看合约部署结果:

client getreceipt --hash 0x80cb46ef3e3350e5c681397444f2b180624a9c1d534927a12e78cd689ef022fe

得到如下结果:

{
    "contract": "0x47a99059219055cf8277d5d7dff933446edb0012",
    "failed": false,
    "poststate": "0x7a6b4d2f7b09e1bdaacb3185c2013f361ea9dc0b05a233ecd268188098878874",
    "result": "0x6080604052600436106049576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806360fe47b114604e5780636d4ce63c146085575b600080fd5b348015605957600080fd5b50608360048036036020811015606e57600080fd5b810190808035906020019092919050505060ad565b005b348015609057600080fd5b50609760b7565b6040518082815260200191505060405180910390f35b8060008190555050565b6000805490509056fea165627a7a7230582045fa1cc38960a931a2b1cf070ffa20bf25683c97838b5f32de5f37a7d6f5568d0029",
    "totalFee": 837670,
    "txhash": "0x80cb46ef3e3350e5c681397444f2b180624a9c1d534927a12e78cd689ef022fe",
    "usedGas": 83767
}

结果中failed为false表明合约部署成功,contract的值为合约地址

调用合约

使用sendTx调用合约

通过remix获得方法调用字节码

使用client sendtx命令调用合约需要提供合约调用方法的payload信息,可以通过remix获得。在remix右下方已部署的合约处,点击左侧小三角可以看到该合约包含的变量和方法。本示例合约包含set和get方法。在set右侧填入参数值,点击set,即可实现函数调用。日志窗口可以看到调用的结果。点击详情可查看调用详情,其中input的值即为方法调用的字节码。本示例调用set,设置变量值为21,如下图所示:

使用sendtx调用合约

如下的命令调用上述合约中的set方法,设置变量值为21。其中payload 为从remix获得的字节码,from为发起交易的账户,to为合约地址

client sendtx --amount 0   --payload 0x60fe47b10000000000000000000000000000000000000000000000000000000000000015 --from 0x987f6215c30f1505e0d42769c5472b410d6bf961.keystore --to 0x47a99059219055cf8277d5d7dff933446edb0012

执行结果如下:

account: 0x987f6215c30f1505e0d42769c5472b410d6bf961, transaction nonce: 1
transaction sent successfully
{
    "Hash": "0x44925f095e067c00660769d2488ab44a6eb9cf3183767d343f3005e7d60e98d6",
    "Data": {
        "Type": 0,
        "From": "0x987f6215c30f1505e0d42769c5472b410d6bf961",
        "To": "0x47a99059219055cf8277d5d7dff933446edb0012",
        "Amount": 0,
        "AccountNonce": 1,
        "GasPrice": 10,
        "GasLimit": 200000,
        "Timestamp": 0,
        "Payload": "0x60fe47b10000000000000000000000000000000000000000000000000000000000000015"
    },
    "Signature": {
        "Sig": "m8tt0j10uDlhd06HO9M2iW0xQe5ZcX+i1N6D7IkbA91BG4/MMhsonTXUEleYyeKa+V02S96kzd2QhgyMkdBDZQA="
    }
}

通过查询receipt信息,可以获取合约调用结果:

client getreceipt --hash 0x44925f095e067c00660769d2488ab44a6eb9cf3183767d343f3005e7d60e98d6

得到如下结果:

{
    "contract": "0x",
    "failed": false,
    "poststate": "0x3f5f6e4d2747b50a55b9f86952d7eb6cd42976db80a624a3f2472af8508029d0",
    "result": "0x",
    "totalFee": 416950,
    "txhash": "0x44925f095e067c00660769d2488ab44a6eb9cf3183767d343f3005e7d60e98d6",
    "usedGas": 41695
}

注意:调用合约的账户必须是与合约地址同一分片的,Seele目前不支持跨片合约调用

使用call调用合约方法

对于仅获取变量值而不改变合约状态的方法,可以通过call来调用。获取对应方法payload信息和上述sendtx调用合约的方法类似。如调用示例合约中的get方法:

client call --payload 0x6d4ce63c --to 0x47a99059219055cf8277d5d7dff933446edb0012

可以得到如下结果:

{
    "contract": "0x",
    "failed": false,
    "poststate": "0x44f2eb71f9044e8ff3620fae7adf1581a0d1f96cbefbaa546b824de8079c5969",
    "result": "0x0000000000000000000000000000000000000000000000000000000000000015",
    "totalFee": 21696,
    "txhash": "0xbaf65d3280c940d78040535ac925905fdeaefeaf4d210dcc5f0a9d5cd76767d3",
    "usedGas": 21696
}

可以看到,result显示的变量值为之前通过set方法设置的21。

Last updated