我一直在尝试找到以太坊Hello World的示例,并遇到了ThomasConté的精彩文章,该文章展示了如何使用solc和web3编译和部署以太坊智能合约 。
在最新版本的web3中,API已更改为基于Promise,因此我决定翻译Thomas的示例。
让我们开始吧。
安装npm库
在开始之前,我们需要安装以下库:
npm install web3
npm install abi-decoder
npm install ethereumjs-testrpc
这些库做什么?
- web3是用于与以太坊区块链交互的客户端库
- abi-decoder用于解码智能合约的哈希,以便我们可以计算出其中的内容。
- ethereum-testrpc让我们启动以太坊的本地测试版本
智能合约
我们仍将使用与Thomas相同的智能合约。 Token.sol是写在一个聪明的合同密实度的语言,描述了金钱地址之间传输:
合同/Token.sol
pragma solidity ^0.4.0;
contract Token {
mapping (address => uint) public balances;
function Token() {
balances[msg.sender] = 1000000;
}
function transfer(address _to, uint _amount) {
if (balances[msg.sender] < _amount) {
throw;
}
balances[msg.sender] -= _amount;
balances[_to] += _amount;
}
}
每当有人尝试转账时,我们都会在他们的帐户中存入1,000,000,然后假设帐户中有足够的资金,请转入适当的金额。
启动本地以太坊节点
让我们开始一个本地的以太坊节点。 我们将降低汽油价格(您为执行交易而“支付”的金额),因此我们不会用完。
$ ./node_modules/.bin/testrpc --gasPrice 20000
EthereumJS TestRPC v6.0.3 (ganache-core: 2.0.2)
Listening on localhost:8545
先决条件
我们需要加载一些Node.js模块:
const fs = require("fs"),
abiDecoder = require('abi-decoder'),
Web3 = require('web3'),
solc = require('solc');
编译智能合约
接下来,我们将编译我们的智能合约:
const input = fs.readFileSync('contracts/Token.sol');
const output = solc.compile(input.toString(), 1);
const bytecode = output.contracts[':Token'].bytecode;
const abi = JSON.parse(output.contracts[':Token'].interface);
连接以太坊并创建合约对象
现在我们有了ABI (应用程序二进制接口),我们将连接到本地以太坊节点并基于ABI创建合约对象:
let provider = new Web3.providers.HttpProvider("http://localhost:8545");
const web3 = new Web3(provider);
let Voting = new web3.eth.Contract(abi);
将ABI添加到解码器
在与区块链进行交互之前,我们首先将ABI添加到我们的ABI解码器中以供以后使用:
abiDecoder.addABI(abi);
查找(虚拟)以太坊账户
现在我们准备创建一些交易! 我们需要一些以太坊账户来玩,如果我们调用web3.eth.getAccounts,我们可以得到节点控制的账户集合。 由于我们的节点是一个测试帐户,因此这些都是虚拟帐户。
web3.eth.getAccounts().then(accounts => {
accounts.forEach(account => {
console.log(account)
})
});
0xefeaE7B180c7Af4Dfd23207422071599c7dfd2f7
0x3a54BaAFDe6747531a28491FDD2F36Cb61c83663
0x367e1ac67b9a85E438C7fab7648964E5ed12061e
0xB34ECD20Be6eC99e8e9fAF641A343BAc826FFFf1
0xE65587a2951873efE3325793D5729Ef91b15d5b5
0xdA232aEe954a31179E2F5b40E6efbEa27bB89c87
0x7119fEbab069d440747589b0f1fCDDBAdBDd105d
0xCacB2b61dE0Ca12Fd6FECe230d2f956c8Cdfed34
0x4F33BF93612D1B89C8C8872D4Af30Fa2A9CbfaAf
0xA1Ebc0D19dB41A96B5278720F47C2B6Ab2506ccF
在账户之间转账
现在我们有了一些帐户,让我们在它们之间转移一些资金。
var allAccounts;
web3.eth.getAccounts().then(accounts => {
allAccounts = accounts;
Voting.deploy({data: bytecode}).send({
from: accounts[0],
gas: 1500000,
gasPrice: '30000000000000'
}).on('receipt', receipt => {
Voting.options.address = receipt.contractAddress;
Voting.methods.transfer(accounts[1], 10).send({from: accounts[0]}).then(transaction => {
console.log("Transfer lodged. Transaction ID: " + transaction.transactionHash);
let blockHash = transaction.blockHash
return web3.eth.getBlock(blockHash, true);
}).then(block => {
block.transactions.forEach(transaction => {
console.log(abiDecoder.decodeMethod(transaction.input));
});
allAccounts.forEach(account => {
Voting.methods.balances(account).call({from: allAccounts[0]}).then(amount => {
console.log(account + ": " + amount);
});
});
});
});
});
让我们运行:
Transfer lodged. Transaction ID: 0x699cbe40121d6c2da7b36a107cd5f28b35a71aff2a0d584f8e734b10f4c49de4
{ name: 'transfer',
params:
[ { name: '_to',
value: '0xeb25dbd0931386eeab267981626ae3908d598404',
type: 'address' },
{ name: '_amount', value: '10', type: 'uint256' } ] }
0x084181d6fDe8bA802Ee85396aB1d25Ddf1d7D061: 999990
0xEb25dbD0931386eEaB267981626AE3908D598404: 10
0x7deB2487E6Ac40f85fB8f5A3bC6896391bf2570F: 0
0xA15ad4371B62afECE5a7A70457F82A30530630a3: 0
0x64644f3B6B95e81A385c8114DF81663C39084C6a: 0
0xBB68FF2935080c807D5A534b1fc481Aa3fafF1C0: 0
0x38d4A3d635B451Cb006d63ce542950C067D47F58: 0
0x7878bA9138361A08522418BD1c8376Af7220a506: 0
0xf400c0e749Fe02E7073E08d713E0A207dc91FBeb: 0
0x7070d1712a25eb7FCf78A549F17705AA66B0aD47: 0
这段代码:
- 将我们的智能合约部署到区块链
- 将10英镑从帐户1转到帐户2
- 解码该事务并显示输出
- 显示所有虚拟账户的余额
我的ethereum-nursery GitHub存储库中提供了完整的示例 。 Thomas还提供了一个后续文章 ,该文章显示了如何在需要客户端签名的远程节点上部署合同。
翻译自: https://www.javacodegeeks.com/2018/01/ethereum-hello-world-example-using-solc-web3.html