以太坊 eth 部署 Solidity 智能合约

1. 安装 solc 环境

在Ubuntu下安装solc:

$ sudo apt-get install -y software-properties-common
$ sudo add-apt-repository -y ppa:ethereum/ethereum
$ sudo apt-get update
$ sudo apt-get install -y solc

安装完成后,用如下命令查看solc是否安装好:

$ solc --version

2. 编译智能合约

测试代码(Storage.sol):

pragma solidity ^0.4.10;

contract Storage {
    uint256 storedData;

    function set(uint256 data) public {
    storedData = data;
    }

    function get() public constant returns (uint256) {
    return storedData;
    }
}

编译:

echo "var storageOutput=`solc --optimize --combined-json abi,bin,interface Storage.sol`" > storage.js

编译后赋值给你了变量 storageOutput

查看编译结果文件(storage.js)内容:

var storageOutput = {
    "contracts": {
        "Storage.sol:Storage": {
            "abi": "[{\"constant\":false,\"inputs\":[{\"name\":\"data\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]",
            "bin": "608060405234801561001057600080fd5b5060bf8061001f6000396000f30060806040526004361060485763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166360fe47b18114604d5780636d4ce63c146064575b600080fd5b348015605857600080fd5b5060626004356088565b005b348015606f57600080fd5b506076608d565b60408051918252519081900360200190f35b600055565b600054905600a165627a7a723058208157aff69edee57dc9d12d47289d96cfe21fa1e318d916bf9bf3d85da0e5d0ff0029"
        }
    },
    "version": "0.4.24+commit.e67f0147.Linux.g++"
}

其中有2个主要部分:

  • abi

ABI(Application Binary Interface)为合约的接口说明,当合约被编译后,那么它的接口就确定了。

  • bin

合约被编译后的二进制内容。

3. 发布

首先确认geth已经启动,并已经登录到了geth console

(1)加载之前生成的storage.js文件

> loadScript('/路径/storage.js')

加载js文件后,其中的变量 storageOutput 就可以引用了,查看一下:

> storageOutput
{
  contracts: {
    Storage.sol:Storage: {
      abi: "[{\"constant\":false,\"inputs\":[{\"name\":\"data\",\"type\":\"uint256\"}],\"name\":\"set\",\"outputs\":[],\"payable\":false,\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"constant\":true,\"inputs\":[],\"name\":\"get\",\"outputs\":[{\"name\":\"\",\"type\":\"uint256\"}],\"payable\":false,\"stateMutability\":\"view\",\"type\":\"function\"}]",
      bin: "608060405234801561001057600080fd5b5060bf8061001f6000396000f30060806040526004361060485763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166360fe47b18114604d5780636d4ce63c146064575b600080fd5b348015605857600080fd5b5060626004356088565b005b348015606f57600080fd5b506076608d565b60408051918252519081900360200190f35b600055565b600054905600a165627a7a723058208157aff69edee57dc9d12d47289d96cfe21fa1e318d916bf9bf3d85da0e5d0ff0029"
    }
  },
  version: "0.4.24+commit.e67f0147.Linux.g++"
}

就是智能合约的编译结果。

Storage.sol:Storage 下面有2个key,abibin,之后要分别用到,为了使用方便,把他们赋值为2个变量:

> var storageContractAbi = storageOutput.contracts['Storage.sol:Storage'].abi
undefined

> var storageContract = eth.contract(JSON.parse(storageContractAbi))
undefined

> var storageBinCode = "0x" + storageOutput.contracts['Storage.sol:Storage'].bin
undefined

(2)部署

先要解锁账户:

> personal.unlockAccount(eth.accounts[0])
Unlock account 0xf090551f59e907a73c76123377e373cd76da449b
Passphrase:
true

发送部署合约的交易:

> var deployTransationObject = { from: eth.accounts[0], data: storageBinCode, gas: 1000000 };
undefined

> var storageInstance = storageContract.new(deployTransationObject)
undefined

此时网络中有一个待处理的交易:

> txpool.status
{
  pending: 1,
  queued: 0
}
> txpool.inspect.pending
{
  0xE0DDcb2abC5da896764202A6e6Cd9aC937D3A946: {
    0: "contract creation: 0 wei + 1000000 gas × 18000000000 wei"
  }
}

开启挖矿,使这笔交易成功写入区块中:

> miner.start(1);admin.sleepBlocks(1);miner.stop();
true

查看部署结果:

> storageInstance
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "set",
      outputs: [],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "get",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }],
  address: "0x8829cb81c61a4c553fe757422a1dee3fdbef7694",
  transactionHash: "0xc70efd32fb60c2a74d4a0ac3402c0fe7d97c09121ea45dc47f2d2707c25b93bb",
  allEvents: function(),
  get: function(),
  set: function()
}

其中的 transactionHash 是合约的交易地址。

查看交易详情:

> eth.getTransactionReceipt(storageInstance.transactionHash);
{
  blockHash: "0x2bc825af0e96a5ea64dbd6a191773b05db8966e784e72fd0b44b58727e0efec4",
  blockNumber: 2973,
  contractAddress: "0x8829cb81c61a4c553fe757422a1dee3fdbef7694",
  cumulativeGasUsed: 71631,
  from: "0xe0ddcb2abc5da896764202a6e6cd9ac937d3a946",
  gasUsed: 71631,
  logs: [],
  logsBloom: "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
  root: "0x5167b657140527b8dfa28c634946ca539c0d54955d5883d20d403bfa7129f3ea",
  to: null,
  transactionHash: "0xc70efd32fb60c2a74d4a0ac3402c0fe7d97c09121ea45dc47f2d2707c25b93bb",
  transactionIndex: 0
}

其中的 contractAddress 是合约地址,赋值到变量:

> var storageAddress = eth.getTransactionReceipt(storageInstance.transactionHash).contractAddress
undefined

> storageAddress
"0x8829cb81c61a4c553fe757422a1dee3fdbef7694"

4. 调用合约

(1)获取合约

通过合约地址获取合约:

> var storage = storageContract.at(storageAddress);
undefined
> storage
{
  abi: [{
      constant: false,
      inputs: [{...}],
      name: "set",
      outputs: [],
      payable: false,
      stateMutability: "nonpayable",
      type: "function"
  }, {
      constant: true,
      inputs: [],
      name: "get",
      outputs: [{...}],
      payable: false,
      stateMutability: "view",
      type: "function"
  }],
  address: "0x8829cb81c61a4c553fe757422a1dee3fdbef7694",
  transactionHash: null,
  allEvents: function(),
  get: function(),
  set: function()
}

(2)发送一条合约调用交易

> storage.set.sendTransaction(42, {from: eth.accounts[1], gas: 1000000})
"0xec3f97caac33fbbc2e73dadd88e93265814b65cd4f24d7067f9efaf792d49695"

此时网络中有一个待处理的交易:

>  txpool.status
{
  pending: 1,
  queued: 0
}
> txpool.inspect.pending
{
  0xE0DDcb2abC5da896764202A6e6Cd9aC937D3A946: {
    1: "0x8829cB81c61a4C553FE757422A1DeE3fDBef7694: 0 wei + 1000000 gas × 18000000000 wei"
  }
}

(3)挖矿 使交易生效

> miner.start(1);admin.sleepBlocks(1);miner.stop();
true

(4)调用合约查看结果

> storage.get.call()
42

至此,智能合约的部署流程就完成了。

你可能感兴趣的:(以太坊 eth 部署 Solidity 智能合约)