本文是参考《【区块链】DOCKER部署量子链私有网络环境以及部署智能合约实践》和比特币的命令行操作,来通过量子链源码来搭建私有测试网络,并发布智能合约。主要是不习惯docker的操作(命令行太长了),因此就用源代码重来了一次。
1. 源代码编译
参考https://github.com/qtumproject/qtum在ubuntu16上编译源代码,成功后在src目录下生成了qtumd,qtum-cli文件。
2. 启动regtest网络
在src目录下执行:
./qtumd -server -regtest 就可以启动regtest网络
3. 查询当前帐号信息
再启动一个terminal,在src目录下执行:
./qtum-cli -regtest listaccounts
输出:
{
"": 0.00000000,
}
4. 查询帐号对应的地址
./qtum-cli -regtest getaccountaddress ""
输出:
qXgQefNvuvRVsk2DPuqopqRxEujruTa32T
5. 充值
由于是regtest网络,自己挖矿就有了
需要生成5000个区块(比特币挖100个就有钱了):
./qtum-cli -regtest generate 5000
然后查看账户:
./qtum-cli -regtest getbalance
90000000.00000000
看起来不少
6. 新增一个帐号
./qtum-cli -regtest getnewaddress "elikong"
qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
下面我们就可以实现目标:
帐号""地址qXgQefNvuvRVsk2DPuqopqRxEujruTa32T
向帐号"elikong"地址qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
转账100btc
7. 转账
./qtum-cli -regtest sendtoaddress qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42100
8. 挖矿确认
./qtum-cli -regtest generate 1
然后查询数量
./qtum-cli -regtest listaccounts
{
"": 90019899.99923200,
"elikong": 100.00000000
}
可以看到elikong帐号有了100btc
9. 查看系统内置的智能合约
./qtum-cli -regtest listcontracts
输出:
{
"0000000000000000000000000000000000000083": 0.00000000,
"0000000000000000000000000000000000000082": 0.00000000,
"0000000000000000000000000000000000000081": 0.00000000,
"0000000000000000000000000000000000000084": 0.00000000,
"0000000000000000000000000000000000000080": 0.00000000
}
10. 编写智能合约
打开http://remix.ethereum.org,输入:
pragma solidity ^0.4.0;
contract Greeter
{
address creator;
string greeting = "hello";
function Greeter() public
{
creator = msg.sender;
// greeting = _greeting;
}
function greet() constant returns (string)
{
return greeting;
}
function setGreeting(string _newgreeting)
{
greeting = _newgreeting;
}
/**********
Standard kill() function to recover funds
**********/
function kill()
{
if (msg.sender == creator)
suicide(creator); // kills this contract and sends remaining funds back to creator
}
}
点击右边的detail,bytecode里面复制object的内容:
60806040526040805190810160405280600581526020017f68656c6c6f0000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100a2565b5034801561005c57600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610147565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e357805160ff1916838001178555610111565b82800160010185558215610111579182015b828111156101105782518255916020019190600101906100f5565b5b50905061011e9190610122565b5090565b61014491905b80821115610140576000816000905550600101610128565b5090565b90565b61038a806101566000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029
11. 发布智能合约
./qtum-cli -regtest createcontract 60806040526040805190810160405280600581526020017f68656c6c6f0000000000000000000000000000000000000000000000000000008152506001908051906020019061004f9291906100a2565b5034801561005c57600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610147565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100e357805160ff1916838001178555610111565b82800160010185558215610111579182015b828111156101105782518255916020019190600101906100f5565b5b50905061011e9190610122565b5090565b61014491905b80821115610140576000816000905550600101610128565b5090565b90565b61038a806101566000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029 2500000 0.00000049 qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
输出:
{
"txid": "1cbe4562ede3ddba2e507d3fad73fc47a8d6d098fd47a32cf2feb4032a1cf901",
"sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",
"hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7",
"address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b"
}
检查智能合约:
./qtum-cli -regtest generate 1
./qtum-cli -regtest listcontracts
输出:
{
"0000000000000000000000000000000000000082": 0.00000000,
"0000000000000000000000000000000000000080": 0.00000000,
"0000000000000000000000000000000000000083": 0.00000000,
"e62b8bc805c33184d9713f7fb1e20606dcfe7a9b": 0.00000000,
"0000000000000000000000000000000000000084": 0.00000000,
"0000000000000000000000000000000000000081": 0.00000000
}
上面红色部分就是刚才发布的合约地址
查询详细:
./qtum-cli -regtest getaccountinfo e62b8bc805c33184d9713f7fb1e20606dcfe7a9b
输出:
{
"address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
"balance": 0,
"storage": {
"290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563": {
"0000000000000000000000000000000000000000000000000000000000000000": "0000000000000000000000007f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"
},
"b10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6": {
"0000000000000000000000000000000000000000000000000000000000000001": "68656c6c6f00000000000000000000000000000000000000000000000000000a"
}
},
"code": "608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806341c0e1b51461005c578063a413686214610073578063cfae3217146100dc575b600080fd5b34801561006857600080fd5b5061007161016c565b005b34801561007f57600080fd5b506100da600480360381019080803590602001908201803590602001908080601f01602080910402602001604051908101604052809392919081815260200183838082843782019150505050505091929192905050506101fd565b005b3480156100e857600080fd5b506100f1610217565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610131578082015181840152602081019050610116565b50505050905090810190601f16801561015e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614156101fb576000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b565b80600190805190602001906102139291906102b9565b5050565b606060018054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156102af5780601f10610284576101008083540402835291602001916102af565b820191906000526020600020905b81548152906001019060200180831161029257829003601f168201915b5050505050905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106102fa57805160ff1916838001178555610328565b82800160010185558215610328579182015b8281111561032757825182559160200191906001019061030c565b5b5090506103359190610339565b5090565b61035b91905b8082111561035757600081600090555060010161033f565b5090565b905600a165627a7a72305820eb4609861a4d53088ea938f7cc4a477805113f4f31baa67746f137848c4450f90029"
}
12. 运行智能合约
继续回到http://remix.ethereum.org里面的detail,复制FUNCTIONHASHES里面的数据:
{
"cfae3217": "greet()",
"41c0e1b5": "kill()",
"a4136862": "setGreeting(string)"
}
./qtum-cli -regtest callcontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9bcfae3217
输出:
{
"address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
"executionResult": {
"gasUsed": 22742,
"excepted": "None",
"newAddress": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
"output": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000",
"codeDeposit": 0,
"gasRefunded": 0,
"depositSize": 0,
"gasForDeposit": 0
},
"transactionReceipt": {
"stateRoot": "c0a81c3cac5aa655116ca988620a4f88483244e2e985d4665dc8c04c959dcb2d",
"gasUsed": 22742,
"bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"log": [
]
}
}
13. 安装ethabi
由于ethabi在ubuntu上只能通过cargo安装,因此需要先安装cargo
sudo apt install cargo
然后安装ethabi
cargo install ethabi-cli
查看合约输出内容,就是解码上面的output内容
ethabi decode params -t string 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000568656c6c6f000000000000000000000000000000000000000000000000000000
输出:
string hello
14. 调用setGreeting
这里需要使用ethabi构造输入参数
先从http://remix.ethereum.org里面的detail复制abi,保存为文件greet.json
[
{
"constant": false,
"inputs": [],
"name": "kill",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": false,
"inputs": [
{
"name": "_newgreeting",
"type": "string"
}
],
"name": "setGreeting",
"outputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "function"
},
{
"constant": true,
"inputs": [],
"name": "greet",
"outputs": [
{
"name": "",
"type": "string"
}
],
"payable": false,
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"payable": false,
"stateMutability": "nonpayable",
"type": "constructor"
}
]
然后构造参数:
ethabi encode function greet.json setGreeting -p "hello world" --lenient
输出:
a41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000
这里对比两个命令
l callcontract 链下完成,不会在区块链上产生记录。不消耗gas
l sendtocontract 链上完成,需要同步,会消耗gas
我们使用下面的命令
sendtocontract "contractaddress""data" (amount gaslimit gasprice senderaddress broadcast)
Send funds and data to a contract.
./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9ba41368620000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000
输出:
{
"txid": "af73f3f087a351ee672bdcd0d93a61b79a72ebc694bbff489b17089e68401c5c",
"sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",
"hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"
}
查询结果:
./qtum-cli -regtest callcontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9bcfae3217
输出:
{
"address": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
"executionResult": {
"gasUsed": 22742,
"excepted": "None",
"newAddress": "e62b8bc805c33184d9713f7fb1e20606dcfe7a9b",
"output": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000",
"codeDeposit": 0,
"gasRefunded": 0,
"depositSize": 0,
"gasForDeposit": 0
},
"transactionReceipt": {
"stateRoot": "6fa927d9a6d5b8794215a5ad465fbd498c051ca3d28046a508fd46aa5f2124ef",
"gasUsed": 22742,
"bloom": "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
"log": [
]
}
}
查询output:
ethabi decode params -t string 0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000b68656c6c6f20776f726c64000000000000000000000000000000000000000000
输出:
string hello world
说明修改成功
(这里没有挖矿,是因为qtum后续自动挖矿了)
15. 合约销毁
就是调用合约的函数kill()
./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5
输出:
{
"txid": "15bd8155a735804946ac5cd24e21a7c414a1806bb9bf6cb65d3431b78628ce84",
"sender": "qYn9XGorExumdxEdx1TVDXBXLzKYFFMRXN",
"hash160": "a6f3e9d2c239bab50b60fb5365d1a3e01f861507"
}
查询合约:
./qtum-cli -regtest listcontracts
输出:
{
"e62b8bc805c33184d9713f7fb1e20606dcfe7a9b": 0.00000000,
"0000000000000000000000000000000000000083": 0.00000000,
"0000000000000000000000000000000000000084": 0.00000000,
"0000000000000000000000000000000000000080": 0.00000000,
"0000000000000000000000000000000000000082": 0.00000000,
"0000000000000000000000000000000000000081": 0.00000000
}
实际并没用删除,因为kill函数内部判断了只能创建者删除,因此,我们使用创建者删除:
./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5 0 250000 0.00000049qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
输出:
error code: -3
error message:
Sender address does not have any unspent outputs
提示没有utxo,但是查询账户
./qtum-cli -regtest listaccounts
{
"": 91959699.69510800,
"elikong": 198.76914800
}
有资金,为啥没有utxo呢?
./qtum-cli -regtest getaccountaddress "elikong"
输出:
qY26EDJjSA2S9wjXdLm9JNtosV52eJN6Cg
发现elikong的地址发生了变化,以前是qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
这个应该就是和比特币不同的地方了,量子链的技术文章里面说实现了虚拟账户层,估计这块就是一个账户对应了多个地址,先不管这个,继续给qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42转账
./qtum-cli -regtest sendtoaddress qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42 100
然后继续执行消耗合约:
./qtum-cli -regtest sendtocontract e62b8bc805c33184d9713f7fb1e20606dcfe7a9b41c0e1b5 0 250000 0.00000049qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42
输出:
{
"txid": "04ca077bd721063aa0062b7a5d8c3a058181872741e2a88b389fe82dda59ebd1",
"sender": "qVASp4AokEYQ5evDyQF7UBHjKngrR3dr42",
"hash160": "7f4afe6ab9ab538f7d28f08c2687f7681d1cd0d7"
}
查询合约:
./qtum-cli -regtest listcontracts
输出:
{
"0000000000000000000000000000000000000082": 0.00000000,
"0000000000000000000000000000000000000083": 0.00000000,
"0000000000000000000000000000000000000084": 0.00000000,
"0000000000000000000000000000000000000080": 0.00000000,
"0000000000000000000000000000000000000081": 0.00000000
}
合约确实被删除了
(或者用./qtum-cli -regtest getaccountinfo e62b8bc805c33184d9713f7fb1e20606dcfe7a9b)