【区块链学习笔记-04】编码实现:批量生成账号、密钥|批量转账|合约代码调用

ETH网络有正式版和测试版,正式版就是我们现在大家所熟知的ETH主网,那么我们使用的时候就会花真的money了,对于新手想开发合约来说,太贵了。还是用测试版吧,基本上就是免费的。

我查了下说,现在用的比较多的就是Rinkeby,那么我们就以Rinkeby来开始我们的在线开发吧。点击后面的区块浏览器,可以通过区块浏览器查询链上的信息

配置小狐狸metamask

先在配置里面打开显示测试网络

之后你就会看到这几个测试网络,选择Rinkeby测试网络,在Rinkeby链上利用小狐狸,创建一个eth的账号

申请ETH做测试

我们有了自己的账号,但是没有eth该怎么办呢?,这些测试网络都有Faucet,可以去免费申请测试的eth。

例如在Rinkeby的测试网络环境下,我们可以找到类似的水龙头

https://faucet.rinkeby.io/ 这个需要发送twitter进行获得,经常不行啊。。。

https://faucets.chain.link/rinkeby 这个做一下验证就可以获得0.1eth,对于我们日常使用来说应该就够用了。比较快,同时会获得10 test link的币。对于我们后续测试调用合约也可以使用。

尝试导入link token

https://docs.chain.link/docs/link-token-contracts/

查看link的合约,在Rinkeby的测试网络,他的合约地址是 0x01BE23585060835E02B77ef475b0Cc51aA1e0709

那么我们就可以使用metamask直接导入该token

导入成功之后,我们就可以看到我们拥有了同时拥有了10个link的token

至此,我们应该就搭建完一个线上的免费测试环境。真实体验,应该会跟在主网使用是一样的。不知道当初直接在主网开发的人员会会有多爽?

使用web3js和Rinkeby进行交互

之前使用python web3的库的时候对比了下js的web3库,感觉js的好像更好用,所以这次教程就体验一下js的web3库,也可以做个横向的对比。

python:https://web3py.readthedocs.io/

JavaScript:https://web3js.readthedocs.io/

初始化环境

交互的库,js下有两个推荐的

https://docs.ethers.io/
https://web3js.readthedocs.io/

这次先使用web3js

需要你安装node,推荐使用nvm安装node,然后在安装 web3js的库

mkdir web3js
cd web3js
npm install web3

Rinkyby的测试网络的信息

RPC地址: https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161

链 ID:4

区块链浏览器查询:https://rinkeby.etherscan.io

使用web3js库

既然是对比和使用,想达到以下几种方式

  • 进行余额查询
  • 进行账号创建
  • 进行签名转账
  • 调用合约方法

ETH合约代码调用

余额查询

const Web3 = require('web3');

const web3 = new Web3(Web3.givenProvider || 'https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')

const query_blance = async (account) => {
  const b_wei = await web3.eth.getBalance(account)
  blance = web3.utils.fromWei(b_wei, 'ether')
  return blance;
};


(async() => { 
  const account = '0x601f8D3853b94a062CE2eA960BB3a2F5D033B689'
  let blance = await query_blance(account)
  console.log(blance)
})()

批量创建账号

https://web3js.readthedocs.io/en/v1.5.2/web3-eth-accounts.html

查看文档,这里有批量创建账号的接口,那么封装一下直接调用即可。

调用完会在本地存储account.csv 文件

const Web3 = require('web3');

const web3 = new Web3(Web3.givenProvider || 'https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')


// 创建账号
const create_account = async () => {
  const account = await web3.eth.accounts.create();
  return account;
};

// 将创建的账号保存到本地csv文件
const save_csv_file = (accounts) => {
  let csv = `address,privateKey\n`
  for (let i = 0; i < accounts.length; i++) {
    const account = accounts[i]
    csv += `\n${account.address},${account.privateKey}`
  }
  const fs = require('fs');
  fs.writeFile('account.csv', csv, function (err) {
    if (err) throw err;
    console.log('Saved!');
  }); 
};

// 批量创建账号
const gen_multi_account = async (num) => {
  const accounts = []
  for (let i = 0; i < num; i++) {
    const account = await create_account()
    accounts.push(account)
  }
  return accounts;
};



// 调用批量创建账号
(async() => { 
  const num = 2
  const accounts = await gen_multi_account(num)  
  save_csv_file(accounts)

})()

将创建的文件,导入metamask

我测试生成了一个新的账号 0xb23B27077aC999924B460C374E5f9192B4fAF16E

通过metamask导入该账号,只需要复制私钥进去就好了

这样我这里就有了一个导入的账号了。

如果我想体验一下从rinkeby-test-account 转账到 js-gen-account那么可以在metamask直接操作,也可以使用代码进行操作

先测试在metamask操作,切换到 rinkeby-test-account 账号,然后对 js-gen-account转账

对其转账0.001,过一会等区块确认,应该就会转账成功

这里就显示成功转账了0.001到js-gen-account的账号

查看账户余额,已经到账。rinkeby-test-account一部分是转给了js-gen账号,另外一部分是消耗的gas费用。所以rinkeby账号会比转账0.001消耗的更多。可以看到下图,各种费用的使用明细。

通过区块链浏览器查询该笔交易

https://rinkeby.etherscan.io/address/0x601f8D3853b94a062CE2eA960BB3a2F5D033B689

通过查看我的测试地址交易信息,即可得到交易的信息。从我的账号1转到了账号2。

进行签名转账

那么如何使用js代码来进行转账呢?

查看文档,可以得知使用sendSignedTransaction来进行转账,那么直接上代码吧。批量转账到的话,可以调用封装一下

// 使用js代码进行转账
(async() => { 
  const Web3 = require('web3');

  const web3 = new Web3(Web3.givenProvider || 'https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')
  // 通过私钥进行转账
  const privateKey = 'you_private_key'
  const account = web3.eth.accounts.privateKeyToAccount(privateKey)
  const to = '0xdC4981d82d6F1e9C6D72762CaBe828cd2A75De5A'
  const value = web3.utils.toWei('0.0005', 'ether')
  const tx = {
    from: account.address,
    to: to,
    value: value,
    gas: '210000',
  }
  const signedTx = await account.signTransaction(tx)
  const result = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
  console.log(result)
})()

批量转账

const Web3 = require('web3');

const web3 = new Web3(Web3.givenProvider || 'https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')


const privateKey = 'your_private_key'

// 通过私钥进行转账
const send_transaction = async (to,amount) => {
  const account = web3.eth.accounts.privateKeyToAccount(privateKey)
  const value = web3.utils.toWei(amount, 'ether')
  gasPrice = await web3.eth.getGasPrice()
  console.log('gasPrice:', gasPrice);

  const tx = {
    nonce: await web3.eth.getTransactionCount(account.address),
    from: account.address,
    to: to,
    value: value,
    gas: 21000,
    gasPrice: gasPrice
  }
  const signedTx = await account.signTransaction(tx)
  const result = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
  console.log(result)
  return result
}




main = async() => { 
  trans_account_list = [
    '0xdC4981d82d6F1e9C6D72762CaBe828cd2A75De5A',
    '0x1BE0Cd87C567b0A5D26845Ab5F0c1EEfa384d613'
  ]
  amount = '0.002'
  // 批量发送转账
  for (let i=0;i<trans_account_list.length;i++){
    await send_transaction(trans_account_list[i],amount)
  }
}


main()

代币LINK合约方法调用

通过上面的代码,我们已经实现了eth的转账,那么下一步我还想实现基于eth代币的一系列操作。我们在领取eth的同时,也领取了10个LINK。那么我们该如何在账号之间对LINK进行转账呢?

先查看文档:https://web3js.readthedocs.io/en/v1.5.2/web3-eth-contract.html

然后查找LINK在Rinkeby上的合约地址:

https://docs.chain.link/docs/link-token-contracts/#ethereum

利用区块链浏览器去查看合约方法

https://rinkeby.etherscan.io/address/0x01BE23585060835E02B77ef475b0Cc51aA1e0709

就看到了合约的方法名

区块浏览器查询代币LINK的余额

有一个balanceOf的方法,点击就可以查询相应的地址的余额,我的这个账号里面有20个LINK。所以就查出来了。这里的单位应该是wei, 1eth = 1^18 wei

https://rinkeby.etherscan.io/unitconverter?wei=20000000000000000000 转换一下就是 20 LINK

那么如何使用代码来交互呢?看文档示例:

var Contract = require('web3-eth-contract');

// set provider for all later instances to use
Contract.setProvider('ws://localhost:8546');

var contract = new Contract(jsonInterface, address);

contract.methods.somFunc().send({from: ....})
.on('receipt', function(){
    ...
});

这里需要一个jsonInterface,和address

应该就是ABI和合约地址,从上述区块链浏览器中已经得知

https://rinkeby.etherscan.io/address/0x01BE23585060835E02B77ef475b0Cc51aA1e0709#code

合约地址:0x01BE23585060835E02B77ef475b0Cc51aA1e0709

ABI的话可以直接copy:到本地存为一个json文件

编写代码

const Web3 = require('web3');

const web3 = new Web3(Web3.givenProvider || 'https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')

// read json file
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, './link-abi.json');
const jsonfile = JSON.parse(fs.readFileSync(filePath, 'utf8'));
// json encode
const abi = JSON.parse(jsonfile.result);
// 合约地址
const address = '0x01BE23585060835E02B77ef475b0Cc51aA1e0709'
// 需要查询的合约地址
const query_address = '0xb23B27077aC999924B460C374E5f9192B4fAF16E'

main = async () => {
  const contract = new web3.eth.Contract(abi, address)
  let result_wei = await contract.methods.balanceOf(query_address).call()  
  let result = web3.utils.fromWei(result_wei, 'ether')
  console.log(result);
}

main()

//最后输出20 

进行代币转账测试

通过https://remix.ethereum.org/ 把合约代码放进去编译可以得到他的一些方法

那么当前合约就有以上的一些方法。我们看一下代币转账的合约代码。本质上就两个参数转账即可,一个是to地址,一个是转账的数目,这里是unit256,对应的应该就是wei了

  /**
  * @dev transfer token for a specified address
  * @param _to The address to transfer to.
  * @param _value The amount to be transferred.
  */
  function transfer(address _to, uint256 _value) returns (bool) {
    balances[msg.sender] = balances[msg.sender].sub(_value);
    balances[_to] = balances[_to].add(_value);
    Transfer(msg.sender, _to, _value);
    return true;
  }

那么就依葫芦画瓢来测试一下

address1:0xb23B27077aC999924B460C374E5f9192B4fAF16E 有20个LINK,作为from地址

address2:0xdC4981d82d6F1e9C6D72762CaBe828cd2A75De5A 0个LINK,作为to地址

使用metamask进行转账过程体验

在区块链浏览器可以直接使用write contract 进行转账测试

1.链接上address1的小狐狸

2.输入地址转账

3.需要将金额转换成wei

如下图所示,我们先链接小狐狸,然后进行调用合约转账即可,这里的2000000000000000000对应2个LINK

通过区块链浏览器查询:https://rinkeby.etherscan.io/tx/0xa99c1fe0b3f693c6aa4948be833c8f8ebd849f878eaaee6864a993abcd6c1cf0

就看到转账成功了。

使用代码进行转账

const Web3 = require('web3');

const web3 = new Web3(Web3.givenProvider || 'https://rinkeby.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161')

// read json file
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, './link-abi.json');
const jsonfile = JSON.parse(fs.readFileSync(filePath, 'utf8'));
// json encode
const abi = JSON.parse(jsonfile.result);

const privateKey = '0x20ce5d52d6a86943041a0a71fd9e3fe262e0585d9a9267205331df1da0bd6b6e'
// 转换单位
let amount = web3.utils.toWei('5', 'ether')
console.log("amount", amount);

const to = '0xdC4981d82d6F1e9C6D72762CaBe828cd2A75De5A'

contract_address = '0x01BE23585060835E02B77ef475b0Cc51aA1e0709'

main = async () => {
  const contract = new web3.eth.Contract(abi, contract_address)
  // transfer

  const account = web3.eth.accounts.privateKeyToAccount(privateKey)
  gasPrice = await web3.eth.getGasPrice()
  console.log('gasPrice:', gasPrice);
      // 发送合约执行信息到合约地址
  const tx = {
    nonce: await web3.eth.getTransactionCount(account.address),
    from: account.address,
    to: contract_address,
    value: "0x0",
    gas: 220000,
    gasPrice: gasPrice,
    data: contract.methods.transfer(to, amount).encodeABI()
  }
  console.log(tx);
  // 进行签名,并发送转账
  const signedTx = await account.signTransaction(tx)
  const result = await web3.eth.sendSignedTransaction(signedTx.rawTransaction)
  console.log(result)
}

main()

至此,我们就完成再区块链上调用合约,并进行转账了。

同理应该就可以扩展到bsc链,进行合约的调用。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇