# solidity智能合约在moonbeam上测试(mac os) **Published by:** [Franco](https://paragraph.com/@franco/) **Published on:** 2022-05-20 **URL:** https://paragraph.com/@franco/solidity-moonbeam-mac-os ## Content 大致先归纳下几个步骤和目标 目标:在polkatdot的moonbeam链上发布智能合约solidity,使用web3.js连接测试 步骤:安装moonbeam节点账号工具脚本发布solidity脚本 需要安装和工具:noderustcargo连接外部网络工具步骤: 1.安装moonbeam节点 1.1获取moonbeam的node dockerdocker pull purestake/moonbeam:v0.23.0 1.2用docker启动nodedocker run --rm --name moonbeam_development -p 9944:9944 -p 9933:9933 \ purestake/moonbeam:v0.23.0 \ --dev --ws-external --rpc-external 如果启动成功,输出有了moonbeam链, 接下来需要提供一个后台服务,生产环境建议OnFinality或是Blast,我们这里就直接使用127.0.0.1:9944做后台服务。 2接下来会写两个脚本,第一个检查账号,第二个发动交易。创建node工程创建脚本 2.1创建工程mkdir web3-examples && cd web3-examples npm install web3 solc@0.8.0 2.2 账户脚本(balances.js) 检查两个账号:0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac 和 0x3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0,这里是随机选择的,也可以别的账号,账号查看打开 https://polkadot.js.org/apps/#/accounts// 1. Add the Web3 provider logic here: // {...} const Web3 = require('web3'); //Create web3 instance const web3 = new Web3('http://127.0.0.1:9933'); // 2. Create address variables const addressFrom = '0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac'; const addressTo = '0x3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0'; // 3. Create balances function const balances = async () => { // 4. Fetch balance info const balanceFrom = web3.utils.fromWei(await web3.eth.getBalance(addressFrom), 'ether'); const balanceTo = web3.utils.fromWei(await web3.eth.getBalance(addressTo), 'ether'); console.log(`The balance of ${addressFrom} is: ${balanceFrom} ETH`); console.log(`The balance of ${addressTo} is: ${balanceTo} ETH`); }; // 5. Call balances function balances(); 执行node balances.js 输出The balance of 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac is: 1207825.819614629174706176 ETH The balance of 0x3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0 is: 1208925.819614629174706176 ETH 看到上面的输出就代表脚本正确执行了。 2.3交易脚本(transaction.js) 从一个账户转移eth到另外一个账号// 1. Add the Web3 provider logic here: // {...} // 2. Create account variables const accountFrom = { privateKey: 'YOUR-PRIVATE-KEY-HERE', address: 'PUBLIC-ADDRESS-OF-PK-HERE', }; const addressTo = 'ADDRESS-TO-HERE'; // Change addressTo // 3. Create send function const send = async () => { console.log(`Attempting to send transaction from ${accountFrom.address} to ${addressTo}`); // 4. Sign tx with PK const createTransaction = await web3.eth.accounts.signTransaction( { gas: 21000, to: addressTo, value: web3.utils.toWei('1', 'ether'), }, accountFrom.privateKey ); // 5. Send tx and wait for receipt const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction); console.log(`Transaction successful with hash: ${createReceipt.transactionHash}`); }; // 6. Call send function send(); 执行node transaction.js 输出Attempting to send transaction from 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac to 0x3Cd0A705a2DC65e5b1E1205896BaA2be8A07c6e0 Transaction successful with hash: 0xb1f3e505fbb1540d8eba2ea574824608878de839cbd29c27f9a0ef6cec146b00 ok ,成功。这个时候你可以再次查询balance脚本查看是否有变化。 接下来步入主要的内容了,发布solidity智能合约了。 3发布智能合约solidity 3.1智能合约(Incrementer.sol)// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract Incrementer { uint256 public number; constructor(uint256 _initialNumber) { number = _initialNumber; } function increment(uint256 _value) public { number = number + _value; } function reset() public { number = 0; } } 3.2编译脚本(compile.js)// 1. Import packages const fs = require('fs'); const solc = require('solc'); // 2. Get path and load contract const source = fs.readFileSync('Incrementer.sol', 'utf8'); // 3. Create input object const input = { language: 'Solidity', sources: { 'Incrementer.sol': { content: source, }, }, settings: { outputSelection: { '*': { '*': ['*'], }, }, }, }; // 4. Compile the contract const tempFile = JSON.parse(solc.compile(JSON.stringify(input))); const contractFile = tempFile.contracts['Incrementer.sol']['Incrementer']; // 5. Export contract data module.exports = contractFile; 3.3发布脚本(deploy.js)// 1. Import the contract file const contractFile = require('./compile'); // 2. Add the Ethers provider logic here: // {...} // 3. Create address variables const accountFrom = { privateKey: 'YOUR-PRIVATE-KEY-HERE', address: 'PUBLIC-ADDRESS-OF-PK-HERE', }; // 4. Get the bytecode and API const bytecode = contractFile.evm.bytecode.object; const abi = contractFile.abi; // 5. Create deploy function const deploy = async () => { console.log(`Attempting to deploy from account ${accountFrom.address}`); // 6. Create contract instance const incrementer = new web3.eth.Contract(abi); // 7. Create constructor tx const incrementerTx = incrementer.deploy({ data: bytecode, arguments: [5], }); // 8. Sign transacation and send const createTransaction = await web3.eth.accounts.signTransaction( { data: incrementerTx.encodeABI(), gas: await incrementerTx.estimateGas(), }, accountFrom.privateKey ); // 9. Send tx and wait for receipt const createReceipt = await web3.eth.sendSignedTransaction(createTransaction.rawTransaction); console.log(`Contract deployed at address: ${createReceipt.contractAddress}`); }; // 10. Call deploy function deploy(); 上面的私钥和地址替换下 执行node deploy.js 输出Attempting to deploy from account 0xf24FF3a9CF04c71Dbc94D0b566f7A27B94566cac Contract deployed at address: 0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3 ok,成功。 3.4查看智能合约脚本(get.js)// 1. Import the contract abi const { abi } = require('./compile'); // 2. Add the Ethers provider logic here: // {...} // 3. Create address variables const contractAddress = 'CONTRACT-ADDRESS-HERE'; // 4. Create contract instance const incrementer = new web3.eth.Contract(abi, contractAddress); // 5. Create get function const get = async () => { console.log(`Making a call to contract at address: ${contractAddress}`); // 6. Call contract const data = await incrementer.methods.number().call(); console.log(`The current number stored is: ${data}`); }; // 7. Call get function get(); 输出Making a call to contract at address: 0xc01Ee7f10EA4aF4673cFff62710E1D7792aBa8f3 The current number stored is: 5 这里我们看到number stored是5,那是因为我们在发布智能合约的时候,输入的初始化就是5。看deploy.js // 7. Create constructor tx const incrementerTx = incrementer.deploy({ data: bytecode, arguments: [5], }); 上面的各种账号/交易/合约的查询也可以在页面中查看,基本的可以使用 https://moonbeam-explorer.netlify.app/ 里面配置本地连接的 node. 参考: 1.本文整体参考 https://docs.moonbeam.network/builders/build/eth-api/libraries/web3js/#setup-web3-with-moonbeam 2.如何获取moonbeam dev node中的公私钥,参考下面链接 https://docs.moonbeam.network/builders/get-started/networks/moonbeam-dev/ ## Publication Information - [Franco](https://paragraph.com/@franco/): Publication homepage - [All Posts](https://paragraph.com/@franco/): More posts from this publication - [RSS Feed](https://api.paragraph.com/blogs/rss/@franco): Subscribe to updates