当前位置: 首页 > 工具软件 > ganache > 使用案例 >

使用ganache-cli和truffle构建以太坊智能合约,以实现“基于哈希锁定的跨链技术”为例

竺鸿骞
2023-12-01

配置以太坊开发环境

系统与工具的版本:

Ubuntu 21.04
npm 7.5.2
Ganache CLI v6.12.2 (ganache-core: 2.13.2)
Truffle v5.3.4 (core: 5.3.4)
Solidity v0.5.16 (solc-js)
Node v12.21.0
Web3.js v1.3.5

更新源:

$ sudo apt-get update

安装npm:

$ sudo apt-get install npm

使用root权限,然后安装truffle和ganache-cil:

$ sudo su
# npm install -g truffle
# npm install -g ganache-cli

克隆智能合约代码:

$ git clone https://github.com/longyangyi/HashTimeLockContract-yi.git

代码目录结构如下:

HashTimeLockContract-yi
├── contracts
│   ├── HashTimeLockContract.sol 智能合约源码
│   └── Migrations.sol 用于部署
├── migrations
│   └── 1_initial_migration.js 用于部署
└── truffle-config.js 配置文件
  • HashTimeLockContract.sol 中的核心函数功能:
    function newContract(address payable _receiver, bytes32 _hashlock, uint _timelock)
        external
        payable
        fundsSent
        futureTimelock(_timelock)
        returns (bytes32 contractId)
    {
        contractId = sha256(
            abi.encodePacked(
                msg.sender,
                _receiver,
                msg.value,
                _hashlock,
                _timelock
            )
        );

        if (haveContract(contractId))
            revert("Contract already exists");

        contracts[contractId] = LockContract(
            msg.sender,
            _receiver,
            msg.value, //note-louis: sender transfer "msg.value" coins to this contract 
            _hashlock,
            _timelock,
            false,
            false,
            0x0
        );

        emit LogHTLCNew(
            contractId,
            msg.sender,
            _receiver,
            msg.value,
            _hashlock,
            _timelock
        );
    }

    function withdraw(bytes32 _contractId, bytes32 _preimage)
        external
        contractExists(_contractId)
        hashlockMatches(_contractId, _preimage)
        withdrawable(_contractId)
        returns (bool)
    {
        LockContract storage c = contracts[_contractId];
        c.preimage = _preimage;
        c.withdrawn = true;
        c.receiver.transfer(c.amount);
        emit LogHTLCWithdraw(_contractId);
        return true;
    }

部署智能合约

先启动ganache-cli,用于模拟以太坊运行环境:

$ ganache-cli
Ganache CLI v6.12.2 (ganache-core: 2.13.2)

Available Accounts
==================
(0) 0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1 (100 ETH)
(1) 0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85 (100 ETH)
...
Private Keys
==================
(0) 0xab37569222bfd1c8f34650bb37480bbbf124410b1a3d8470582a638d39d6c86e
(1) 0xf4a1ddd0b0e63e86a6c28321ac0cde19409b3955ea1ce0f09db514f43f72ecc9
...
Listening on 127.0.0.1:8545

ganache-cli 工具自动生成多个账户与私钥。
account (0) 0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1放置哈希锁。
account (1) 0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85提供原像preimage解锁。

进入文件夹HashTimeLockContract-yi,使用truffle工具部署智能合约:

$ cd HashTimeLockContract-yi
$ truffle migrate

Compiling your contracts...
===========================
> Compiling ./contracts/HashTimeLockContract.sol
> Artifacts written to /home/louis/HashTimeLockContract-yi/build/contracts
> Compiled successfully using:
   - solc: 0.5.16+commit.9c3226ce.Emscripten.clang



Starting migrations...
======================
> Network name:    'development'
> Network id:      1621335557793
> Block gas limit: 6721975 (0x6691b7)


1_initial_migration.js
======================

   Deploying 'Migrations'
   ----------------------
   > transaction hash:    0x042cb657fc218e799133769ad1be70e2e0b7d6ab8297d3acd654667c7f1ecf97
   > Blocks: 0            Seconds: 0
   > contract address:    0x76E28398a0C0154a1E34ff0a05573603D4832b6e
   > block number:        1
   > block timestamp:     1621335566
   > account:             0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1
   > balance:             99.99549526
   > gas used:            225237 (0x36fd5)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.00450474 ETH


   Deploying 'HashTimeLockContract'
   --------------------------------
   > transaction hash:    0x1d1dceabb99006c39c2fac2c0add470ce2ed71460ad529e1ee0f63165b4b3a14
   > Blocks: 0            Seconds: 0
   > contract address:    0x9D9baf837F31C0C34060539Dab5A8bE9e60CaB28
   > block number:        2
   > block timestamp:     1621335567
   > account:             0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1
   > balance:             99.97478414
   > gas used:            1035556 (0xfcd24)
   > gas price:           20 gwei
   > value sent:          0 ETH
   > total cost:          0.02071112 ETH


   > Saving migration to chain.
   > Saving artifacts
   -------------------------------------
   > Total cost:          0.02521586 ETH


Summary
=======
> Total deployments:   2
> Final cost:          0.02521586 ETH

得到了contract address,就是部署成功后智能合约的地址:
0x9D9baf837F31C0C34060539Dab5A8bE9e60CaB28。

  • ganache-cli 窗口显示产生区块的过程:
  Transaction: 0x042cb657fc218e799133769ad1be70e2e0b7d6ab8297d3acd654667c7f1ecf97
  Contract created: 0x76e28398a0c0154a1e34ff0a05573603d4832b6e
  Gas usage: 225237
  Block Number: 1
  Block Time: Tue May 18 2021 18:59:26 GMT+0800 (China Standard Time)

eth_getTransactionReceipt
eth_getCode
eth_getTransactionByHash
eth_getBlockByNumber
eth_getBalance
net_version
eth_getBlockByNumber
eth_getBlockByNumber
net_version
eth_getBlockByNumber
eth_estimateGas
net_version
eth_blockNumber
eth_getBlockByNumber
eth_sendTransaction

  Transaction: 0x1d1dceabb99006c39c2fac2c0add470ce2ed71460ad529e1ee0f63165b4b3a14
  Contract created: 0x9d9baf837f31c0c34060539dab5a8be9e60cab28
  Gas usage: 1035556
  Block Number: 2
  Block Time: Tue May 18 2021 18:59:27 GMT+0800 (China Standard Time)

eth_getTransactionReceipt
eth_getCode
eth_getTransactionByHash
eth_getBlockByNumber
eth_getBalance
eth_getBlockByNumber
eth_getBlockByNumber
eth_sendTransaction

  Transaction: 0xcf0c5d2d74bd863a4c649b421e4a708c91eae1c7c42c2b320e872ea97084e5b7
  Gas usage: 42363
  Block Number: 3
  Block Time: Tue May 18 2021 18:59:27 GMT+0800 (China Standard Time)

此时智能合约已经在ganache-cli上成功运行。

调用智能合约

  • 使用truffle控制台:
$ truffle console

定义一个变量:
truffle(development)> var contract
undefined

获取智能合约实例:
truffle(development)> HashTimeLockContract.deployed().then(function(instance){contract= instance;})
undefined

调用智能合约中的函数,()里的函数参数请参照前文中的函数代码,{}里代表交易发起者和交易金额:
truffle(development)> let result = await contract.newContract.sendTransaction("0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85", "0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925", "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", {from: "0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1", value: web3.utils.toWei('10', 'ether')})
undefined
  • ganache-cli 同步产生区块:
  Transaction: 0x7b0fa92a508ae139a00fad34650f476a8020f30a682e112deee44664a01a287d
  Gas usage: 134656
  Block Number: 4
  Block Time: Tue May 18 2021 19:04:44 GMT+0800 (China Standard Time)
  • 查看日志中的函数返回值:
truffle(development)> result.receipt.logs
[
  {
    logIndex: 0,
    transactionIndex: 0,
    transactionHash: '0x7b0fa92a508ae139a00fad34650f476a8020f30a682e112deee44664a01a287d',
    blockHash: '0xdb420eb823c1260dc387c2bc605d4596d3ac207dbe7ffed996408ef455253b82',
    blockNumber: 4,
    address: '0x9D9baf837F31C0C34060539Dab5A8bE9e60CaB28',
    type: 'mined',
    removed: false,
    id: 'log_c0c74164',
    event: 'LogHTLCNew',
    args: Result {
      '0': '0xb63552c6ff936222e485d73f300d0e08ef487690eba066a2b607c05a1fd0b164',
      '1': '0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1',
      '2': '0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85',
      '3': [BN],
      '4': '0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925',
      '5': [BN],
      __length__: 6,
      contractId: '0xb63552c6ff936222e485d73f300d0e08ef487690eba066a2b607c05a1fd0b164',
      sender: '0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1',
      receiver: '0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85',
      amount: [BN],
      hashlock: '0x66687aadf862bd776c8fc18b8e9f8e20089714856ee233b3902a591d0d5f2925',
      timelock: [BN]
    }
  }
]

日志中存在返回值contractId: ‘0xb63552c6ff936222e485d73f300d0e08ef487690eba066a2b607c05a1fd0b164’。

  • 查看账户余额,智能合约的地址也能查看到余额:
truffle(development)> web3.eth.getBalance("0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1")
'89971243760000000000' 账户(0)减少10 ether和少量交易费
truffle(development)> web3.eth.getBalance("0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85")
'100000000000000000000' 账户(1)不变
truffle(development)> web3.eth.getBalance("0x9d9baf837f31c0c34060539dab5a8be9e60cab28")
'10000000000000000000' 智能合约的账户增加10 ether
  • 调用另一个函数,函数参数请参照前文的智能合约代码:
truffle(development)> contract.withdraw("0xb63552c6ff936222e485d73f300d0e08ef487690eba066a2b607c05a1fd0b164", "0x0000000000000000000000000000000000000000000000000000000000000000", {from: "0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85"})
{
  tx: '0x21d3361666cc50221416790abd35d236121f8e444c5dbdfc854a6404a4329c15',
  receipt: {
    transactionHash: '0x21d3361666cc50221416790abd35d236121f8e444c5dbdfc854a6404a4329c15',
    transactionIndex: 0,
    blockHash: '0x9d3c674ba28a4ed5879408a0ca79c40378d43feb79d2c0bfcf9b7eeed0820f0c',
    blockNumber: 5,
    from: '0x7a01354de9f3cbfe121cbd2183b6f8bbc9cf1a85',
    to: '0x9d9baf837f31c0c34060539dab5a8be9e60cab28',
    gasUsed: 60168,
    cumulativeGasUsed: 60168,
    contractAddress: null,
    logs: [ [Object] ],
    status: true,
    logsBloom: '0x00000000000000000000800000000000000000000400000000000000000000010000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000',
    rawLogs: [ [Object] ]
  },
  logs: [
    {
      logIndex: 0,
      transactionIndex: 0,
      transactionHash: '0x21d3361666cc50221416790abd35d236121f8e444c5dbdfc854a6404a4329c15',
      blockHash: '0x9d3c674ba28a4ed5879408a0ca79c40378d43feb79d2c0bfcf9b7eeed0820f0c',
      blockNumber: 5,
      address: '0x9D9baf837F31C0C34060539Dab5A8bE9e60CaB28',
      type: 'mined',
      removed: false,
      id: 'log_0638e82b',
      event: 'LogHTLCWithdraw',
      args: [Result]
    }
  ]
}
  • ganache-cli 同步产生区块:
  Transaction: 0x21d3361666cc50221416790abd35d236121f8e444c5dbdfc854a6404a4329c15
  Gas usage: 60168
  Block Number: 5
  Block Time: Tue May 18 2021 19:10:02 GMT+0800 (China Standard Time)

再次查看余额:

truffle(development)> web3.eth.getBalance("0x4ab7fCA3bbb0dd145D9715adD1396e8718E9b0C1")
'89971243760000000000'
truffle(development)> web3.eth.getBalance("0x7A01354De9F3CbfE121CBD2183B6f8Bbc9Cf1a85")
'109998796640000000000' 账户(1)增加10 ether
truffle(development)> web3.eth.getBalance("0x9d9baf837f31c0c34060539dab5a8be9e60cab28")
'0' 智能合约账户余额清零

至此便实现了account(0)中的10 ether通过哈希锁定的方式转移至account(1)。

 类似资料: