Ubuntu18.04使用remix部署智能合约

1. 使用remix编译智能合约

① 编写智能合约
  • 我也是新手,智能合约就是在网上找的,一共找了两个。一个是multiply_test.sol,内容如下:
pragma solidity 0.4.24;
contract multiply_test {
    function mul(uint a) pure public returns (uint) {
        return a*12;
    }
}
  • 第二个是Test.sol,内容如下:
pragma solidity 0.4.24;

contract Test{
    
    string public name;
    
    constructor() public {
        name = "lucy";
    }
    
    function getName() public view returns (string) {
        return name;
    }
    
    function setName(string _name) public {
        name = _name;
    }
}
② 选择自动编译

Ubuntu18.04使用remix部署智能合约_第1张图片

  • 点击details,查看两个智能合约对应的web3 deploy的内容。
    multiply_test.solweb3 deploy的内容:
var multiply_testContract = web3.eth.contract([{"constant":true,"inputs":[{"name":"a","type":"uint256"}],"name":"mul","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]);
var multiply_test = multiply_testContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })

Test.solweb3 deploy的内容:

var testContract = web3.eth.contract([{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]);
var test = testContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x608060405234801561001057600080fd5b506040805190810160405280600481526020017f6c756379000000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610410806101166000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461005c57806317d7de7c146100ec578063c47f00271461017c575b600080fd5b34801561006857600080fd5b506100716101e5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b1578082015181840152602081019050610096565b50505050905090810190601f1680156100de5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100f857600080fd5b50610101610283565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610141578082015181840152602081019050610126565b50505050905090810190601f16801561016e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561018857600080fd5b506101e3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610325565b005b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561031b5780601f106102f05761010080835404028352916020019161031b565b820191906000526020600020905b8154815290600101906020018083116102fe57829003601f168201915b5050505050905090565b806000908051906020019061033b92919061033f565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b6103e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a723058203ee99201eee4e947f71128a9e8a8f4149ad48ca0d230419e31abb3712f983cf90029', 
     gas: '4700000'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })
③ 使用solc命令编译

编译命令如下:

$ solc /home/hadoop/solidity/MyTest.sol --bin --abi --optimize -o ~/solidity
Compiler run successful. Artifact(s) can be found in directory /home/hadoop/solidity.

会在~/solidity下出现对应的abi和bin文件。
Ubuntu18.04使用remix部署智能合约_第2张图片

2. 在私有链上部署智能合约(以multiply_test.sol为例)

  • 获取 abi的内容,即web3 deployweb3.eth.contract(xxxx)中的xxxx建议: 不要直接粘贴上图中ABI的内容,这个内容粘贴出来有换行,需要自己整理,比较麻烦。
> abi_mul = [{"constant":true,"inputs":[{"name":"a","type":"uint256"}],"name":"mul","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"}]
[{
    constant: true,
    inputs: [{
        name: "a",
        type: "uint256"
    }],
    name: "mul",
    outputs: [{
        name: "",
        type: "uint256"
    }],
    payable: false,
    stateMutability: "pure",
    type: "function"
}]
  • abi的内容放到web3.eth.contract()中去,创建合约。可以直接粘贴web3 deploy中的内容,将具体的abi改为abi_mul
> multiply_testContract  = web3.eth.contract(abi_mul)
{
  abi: [{
      constant: true,
      inputs: [{...}],
      name: "mul",
      outputs: [{...}],
      payable: false,
      stateMutability: "pure",
      type: "function"
  }],
  eth: {
    accounts: ["0x4161514855682c94e3cbcb4808eb8766cf889e17", "0xa070a468bfb29e807fa09b2876b543dc2e9f9424", "0xd4c057bbda47d12229f71c474be330d0b1a37780"],
    blockNumber: 302,
    ...
  },
  at: function(address, callback),
  getData: function(),
  new: function()
}
  • 计算需要的 gas,避免gas浪费。这时需要使用bytecode,也就是web3 deploymultiply_testContract.new()中的data:
> mul_data = '0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029'
"0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029"
> mul_gasValue = eth.estimateGas({data:mul_data})
102751
  • 部署合约,直接粘贴web3 deploy第二个var的内容,只需要将gas改为我们计算出来的 mul_gasValue的值 :
> multiply_test = multiply_testContract.new(
   {
     from: web3.eth.accounts[0], 
     data: '0x608060405234801561001057600080fd5b5060bb8061001f6000396000f300608060405260043610603f576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff168063131e2f18146044575b600080fd5b348015604f57600080fd5b50606c600480360381019080803590602001909291905050506082565b6040518082815260200191505060405180910390f35b6000600c820290509190505600a165627a7a723058202e8291b99896a921cc82fde46202082fa88f7c1e2bf326d5c368cd4f0f9ce76c0029', 
     gas: '102751'
   }, function (e, contract){
    console.log(e, contract);
    if (typeof contract.address !== 'undefined') {
         console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
    }
 })
INFO [03-26|10:14:34.627] Setting new local account                address=0x4161514855682C94e3CBcb4808eb8766cf889e17
INFO [03-26|10:14:34.627] Submitted contract creation              fullhash=0xbeff6afbc46ba3e0a9d7259437359f3a3eb1d462f000604fcf82f6282a113384 contract=0xe2715bcf75AdaF302C0DE53A4beBB5bB9e5FB3e7
null [object Object]
{
  abi: [{
      constant: true,
      inputs: [{...}],
      name: "mul",
      outputs: [{...}],
      payable: false,
      stateMutability: "pure",
      type: "function"
  }],
  address: undefined,
  transactionHash: "0xbeff6afbc46ba3e0a9d7259437359f3a3eb1d462f000604fcf82f6282a113384"
}
  • 部署合约可能会出现的问题:
    ① 账户没有解锁
Error: authentication needed: password or unlock undefined

解决办法: 解锁账户

> personal.unlockAccount(eth.accounts[0],"123456",0)
true

② 账户余额不足

Error: insufficient funds for gas * price + value undefined

解决办法: 挖矿

  • 合约部署完成后,我们会发现txpool中有待确认的交易。部署合约的过程实际也是由创建合约的账户发送的一笔交易(即eth.coinbase账户),需要挖矿进行确认,否则合约实例multiply_testaddressundefined
> txpool.status
{
  pending: 1,
  queued: 0
}
> miner.start(1)
...
//发现有以下信息,说明合约已经成功部署。
Contract mined! address: 0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7 transactionHash: 0xbeff6afbc46ba3e0a9d7259437359f3a3eb1d462f000604fcf82f6282a113384
  • 查询multiply_test.address属性,发现就是合约部署成功的提示信息中address。这个合约地址可以记录到你的文件夹中,方便以后使用智能合约时,输入对应的合约地址!
    PS: 自己就是个傻逼,一直用外部账户的地址eth.accounts[0]去调用已经部署好的智能合约,搞了一个晚上,人家说地址不会自己都没反应过来。。。。
> multiply_test.address
"0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7"

3. 调用智能合约

① 使用刚刚生成的multiply_test去调用智能合约
> multiply_test.mul(12)
144
② 通过abi去调用智能合约(在另外一个节点上测试)
//abi_mul的定义如上,不再赘述
//使用eth.contract(abi_mul)获取合约对象,at(multiply_test.address)实例化合约
> mul_contract = eth.contract(abi_mul).at("0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7")
{
  abi: [{
      constant: true,
      inputs: [{...}],
      name: "mul",
      outputs: [{...}],
      payable: false,
      stateMutability: "pure",
      type: "function"
  }],
  address: "0xe2715bcf75adaf302c0de53a4bebb5bb9e5fb3e7",
  transactionHash: null,
  allEvents: function(),
  mul: function()
}
//调用合约实现乘法计算
> mul_contract.mul(5)
60
  • 注意: at()中的地址是合约地址!!!!不然报错如下:
Error: new BigNumber() not a base 16 number: 
    ...

参考链接:
【区块链】记录合约开发中遇到的坑
Error: new BigNumber() not a base 16 number
What does the Web3 “BigNumber not a base 16 number Error” mean

4. 第二个智能合约的部署以及调用

  • 部署过程跟multiply_test.sol一样,不再赘述。
> abi_test=[{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getName","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"_name","type":"string"}],"name":"setName","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]
> testContract = web3.eth.contract(abi_test)
> test_data='0x608060405234801561001057600080fd5b506040805190810160405280600481526020017f6c756379000000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610410806101166000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461005c57806317d7de7c146100ec578063c47f00271461017c575b600080fd5b34801561006857600080fd5b506100716101e5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b1578082015181840152602081019050610096565b50505050905090810190601f1680156100de5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100f857600080fd5b50610101610283565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610141578082015181840152602081019050610126565b50505050905090810190601f16801561016e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561018857600080fd5b506101e3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610325565b005b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561031b5780601f106102f05761010080835404028352916020019161031b565b820191906000526020600020905b8154815290600101906020018083116102fe57829003601f168201915b5050505050905090565b806000908051906020019061033b92919061033f565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b6103e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a723058203ee99201eee4e947f71128a9e8a8f4149ad48ca0d230419e31abb3712f983cf90029'

> test_gasValue = eth.estimateGas({data:test_data})
363932
> test = testContract.new(
...    {
......      from: web3.eth.accounts[0], 
......      data: '0x608060405234801561001057600080fd5b506040805190810160405280600481526020017f6c756379000000000000000000000000000000000000000000000000000000008152506000908051906020019061005c929190610062565b50610107565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106100a357805160ff19168380011785556100d1565b828001600101855582156100d1579182015b828111156100d05782518255916020019190600101906100b5565b5b5090506100de91906100e2565b5090565b61010491905b808211156101005760008160009055506001016100e8565b5090565b90565b610410806101166000396000f300608060405260043610610057576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde031461005c57806317d7de7c146100ec578063c47f00271461017c575b600080fd5b34801561006857600080fd5b506100716101e5565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156100b1578082015181840152602081019050610096565b50505050905090810190601f1680156100de5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b3480156100f857600080fd5b50610101610283565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610141578082015181840152602081019050610126565b50505050905090810190601f16801561016e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561018857600080fd5b506101e3600480360381019080803590602001908201803590602001908080601f0160208091040260200160405190810160405280939291908181526020018383808284378201915050505050509192919290505050610325565b005b60008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561027b5780601f106102505761010080835404028352916020019161027b565b820191906000526020600020905b81548152906001019060200180831161025e57829003601f168201915b505050505081565b606060008054600181600116156101000203166002900480601f01602080910402602001604051908101604052809291908181526020018280546001816001161561010002031660029004801561031b5780601f106102f05761010080835404028352916020019161031b565b820191906000526020600020905b8154815290600101906020018083116102fe57829003601f168201915b5050505050905090565b806000908051906020019061033b92919061033f565b5050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f1061038057805160ff19168380011785556103ae565b828001600101855582156103ae579182015b828111156103ad578251825591602001919060010190610392565b5b5090506103bb91906103bf565b5090565b6103e191905b808211156103dd5760008160009055506001016103c5565b5090565b905600a165627a7a723058203ee99201eee4e947f71128a9e8a8f4149ad48ca0d230419e31abb3712f983cf90029', 
......      gas: '363932'
......    }, function (e, contract){
......     console.log(e, contract);
......     if (typeof contract.address !== 'undefined') {
.........          console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash);
.........     }
......  })
  • 挖矿使合约生效:
Contract mined! address: 0x172afbdc1ff6ffbd985501240aa319178547fc01 transactionHash: 0xa0ea14ca8be7bfefbce2d50116f5d701e7ed911b32f811a782deeb484c21d94e
  • 调用合约。注意: 注意到读操作和写操作是有区别的——写操作要消耗gas,读操作不用。因为写操作需要通过矿工对链做出更改和同步,有代价。这就是为什么getName()可以直接得到结果,而setName()需要指定付款账户并挖矿确认。
> test.getName()
"lucy"
//每次调用set时顺便指定付款账户,这种方法适用于每个账户都经常使用的多账户节点。
> test.setName("john",{from:eth.accounts[0]})
INFO [03-26|11:26:55.527] Submitted transaction                    fullhash=0x8a8b1f254de9e96383d845b2da7009e1c62248e84fb2ff3317471dd2a3176cc3 recipient=0x50ce18662C13d61EA3e10709A896124E6a1A13D7
"0x8a8b1f254de9e96383d845b2da7009e1c62248e84fb2ff3317471dd2a3176cc3"
//通过挖矿让写操作生效
> miner.start(1)
...
> test.getName()
"john"

如果不指定付款账户,报错:

> test.setName("tiger")
Error: invalid address
    at web3.js:3930:15
    at web3.js:3756:20
    at web3.js:5025:28
    at map (<native code>)
    at web3.js:5024:12
    at web3.js:5050:18
    at web3.js:5075:23
    at web3.js:4137:16
    at apply (<native code>)
    at web3.js:4223:16

参考链接:
6分钟以太坊实战系列-以太坊私有链搭建及智能合约部署——gas的估计
区块链学习(2) 智能合约部署到以太坊私有链并交互(mac版)
以太坊搭建私有链和部署智能合约

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