系统与工具的版本:
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 配置文件
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。
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 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
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]
}
]
}
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)。