以太坊开发基础(3)创建交易和部署合约

在以太坊上使用智能合约是需要专门的交易的,我们需要花费一定的ether来调用智能合约,把一定的ether转账到智能合约的地址中。在我们学习实现智能合约之前,先要了解一下如何创建一个交易。

一、发布交易

第一步: 在一个节点上,采用coinbase账户并解锁它。

> coinbaseAddress = eth.coinbase
> personal.unlockAccount(coinbaseAddress)
Unlock account 0x4e7b6e350db51b1cea072dce8a507683cb83f814
Passphrase:
True

第二步:现在从另一个节点的coinbase帐户或者其他账户复制地址,并回到未解锁的帐户节点

> hisAddress = "0xb161ffdc6a63963bfbf7b12069ff52cfe5d42cbc"

第三步:sendTransaction

> eth.sendTransaction({from: eth.coinbase, to: hisAddress, value: 100000000})
INFO [08-24|19:55:15.585] Submitted transaction
fullhash=0x278445d113e9526ee84e7c583dbb65f5d293b80e9b1a836cf0d4e8442e61b560
recipient=0xb161ffDc6A63963BfBF7B12069FF52CfE5D42cBC
"0x278445d113e9526ee84e7c583dbb65f5d293b80e9b1a836cf0d4e8442e61b560"

还有一件需要注意的事,而且会很容易混淆的,就是为什么这些数字的值有那么多0。这是因为值是用wei来表示的,所以不必处理可能在不同系统上引起问题的浮点数。这将与gas(一个与计算步骤大致相当的测量法。每笔交易都需要包括一个Gas限制和一个愿意为每个Gas支付的费用;矿工可以选择进行交易和收费)一起发挥作用 ,需要开始指定合同部署和交易。

如果想知道用这个值发送了多少以太币,命令如下:

> web3.fromWei(100000000,'ether')
“0.0000000001”

第四步:要使交易发送,并且看到不同余额的差异,需要在节点中启动矿工,然后在挖掘了一个区块后停止,现在检查余额以查看变化。

> miner.start()
...............
> miner.stop()
> web3.eth.getBalance(eth.coinbase)
59999999999900000000
> web3.eth.getBalance(hisAddress)
100000000

二、部署合约

部署合约,是把写好的智能合约编译成EVM(Ethereum Virtual Machine)能读懂的二进制编码(Contract Bytecode),储存到区块链上。部署到区块链上的合约会有一个和钱包地址格式一样的合约地址。


合约部署后,使用者需要调用合约提供的方法时,就是要向这个合约地址发起交易。

部署合约多很多种方案,你可以通过web3.js来写一个合约部署的脚本,然后在geth控制台里运行,进行合约部署,也可以通过remix-ide来进行部署,或者在truffle框架内进行部署。

1、Remix IDE编写第一个智能合约

remix ide是开发以太坊智能合约的神器,支持网页在线编写、部署和测试智能合约。网址http://remix.ethereum.org

进入后,新建一个智能合约命名为HelloWrold.sol,合约代码如下:

pragma solidity ^0.4.24;
contract HelloWorld{
    function say() public pure returns(string){
        return "Hello Wrold";
    }
}

 remix可以检测合约代码编写的正确性,如果没有编译通过,将在右侧工具栏中显示。编译通过如下图所示:

2.Remix链接私有链

首先开启我们的私有链环境,然后在remix界面中点击右侧Run按钮,在该界面下将Environment下拉选择Web3 Provider,弹窗问我们是否要链接一个以太坊节点,点击ok后,在新的弹窗中输入我们启动私有链时设置的地址,默认为localhost:8545。点击ok进行链接,链接成功后,可以在account栏中显示出账号信息。

这里需要注意的是,在链接私链的时候会出现下面这个错误:

Not possible to connect to the Web3 provider. Make sure the provider is running and a connection is open (via IPC or RPC).

所以在启动私链的时候一定要使用下面这个参数:

--rpccorsdomain="*"   // 允许跨域请求

完整的命令是:

geth --identity "TestNode1" --datadir "data0" --rpc --rpcapi "db,eth,net,web3" --port "30303" 
--networkid "29382" --ws --wsorigins="*" --rpccorsdomain="*" console

3.使用remix-ide部署智能合约

(1)部署合约之前首先要解锁账号,在geth中输入命令解锁账户:

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

(2)在remix的Run界面点击粉色deploy按钮进行部署,可以在remix的控制台和geth的日志文件中看到私有链中新产生了一个交易。
(3)在geth中开启挖矿等待区块确认

>miner.start()

部署成功后可在remix右侧Run界面显示出合约部署的地址和合约方法供我们进行测试。

4、使用geth部署智能合约

在remix-ide的compile界面,智能合约编译成功后可以看到智能合约的详情:

在弹出的对话框中找到WEB3DEPLOY部分,点拷贝,粘贴到编辑器后,修改初始化字符串为hello world。

var _greeting5 ="hello world" ; 
var helloContract5 = web3.eth.contract([{"constant":true,"inputs":[],"name":"say","outputs":[{"name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"_greeting5","type":"string"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"}]); 
var hello = helloContract5.new( _greeting5, { from: web3.eth.accounts[2], data: '0x606......029', gas: '4700000' }, function (e, contract){ 
    console.log(e, contract); 
    if (typeof contract.address !== 'undefined') { 
        console.log('Contract mined! address: ' + contract.address + ' transactionHash: ' + contract.transactionHash); 
    } 
})

拷贝会geth控制台里,回车后,看到输出,说明合约已经部署成功。

5.测试合约

(1)remix下测试

remix下只需点击say按钮即可,可在控制台查看合约的执行结果。输出为Hello World,测试通过。

(2)geth下测试

在geth下测试实际上是使用web3.js在控制台中操作:

首先,在remix-ide的Run界面复制detail按钮,得到合约的abi(abi是对合约接口的描述);

然后,复制合约地址

合约地址:0x2668d1b0602bc0e1e2f84f931547940546720d75
abi:
[{"constant":true,"inputs":[],"name":"say","outputs":[{"name":"","type":"string"}],"payable":false,
"stateMutability":"pure","type":"function"}

最后,使用web3获取合约实例:

var contract = web3.contract(abi).at(contractAddress);

调用合约方法,输出为 Hello World,测试成功。

> contract.say()
"Hello Wrold"

此清单只为俯瞰一下geth中可以使用哪些方法来与以太坊进行交互,详细的还是要参考官方文档: 可以参考: https://github.com/ethereum/go-ethereum/w ...