golang学习笔记19 用Golang实现以太坊代币转账

  • 在以太坊区块链中,我们称代币为Token,是以太坊区块链中每个人都可以任意发行的数字资产。并且它必须是遵循erc20标准的,至于erc20标准,大家可以参考这篇文章 https://theethereum.wiki/w/index.php/ERC20_Token_Standard
  • 它实际上一段智能合约代码,智能合约代码中必须要有以下的一些function 和 event。
  1. contract ERC20 {
  2. function totalSupply() constant returns (uint totalSupply);
  3. function balanceOf(address _owner) constant returns (uint balance);
  4. function transfer(address _to, uint _value) returns (bool success);
  5. function transferFrom(address _from, address _to, uint _value) returns (bool success);
  6. function approve(address _spender, uint _value) returns (bool success);
  7. function allowance(address _owner, address _spender) constant returns (uint remaining);
  8. event Transfer(address indexed _from, address indexed _to, uint _value);
  9. event Approval(address indexed _owner, address indexed _spender, uint _value);
  10. }

连接以太坊RPC节点

  • 目前广泛使用的是go-ethereum,他的客户端名是geth。你可以通过编译、安装等方式把节点搭建在你的电脑或者服务器中,并开启rpc服务。本文省略这一步骤,网上有很文章供你了解。
  • 附上github:https://github.com/ethereum/go-ethereum
  • geth默认的rpc端口是8545,我使用默认端口,后面我们都用http://127.0.0.1:8545作为我们的rpc连接。

首先获取go-ethereum代码

  • go get github.com/ethereum/go-ethereum
  • 然后我们go-ethereum目录,如果你的golang环境没有问题,那么应该是这个路径。
  • cd $GOPATH/src/github.com/ethereum/go-ethereum
  • 当你进入目录,看到代码已经完整拉取下来,那么我们就可以进行下一步了。

连接RPC节点

  1. import (
  2. "github.com/ethereum/go-ethereum/rpc"
  3. "github.com/ethereum/go-ethereum/ethclient"
  4. )
  5. rpcDial, err := rpc.Dial("http://127.0.0.1:8545")
  6. if err != nil {
  7. panic(err);
  8. }
  9. client := ethclient.NewClient(rpcDial)

  如果没有panic,那么我们已经成功连接了

创建测试账户

  • 要进行转账测试,那么我们需要两个以太坊账户。我们用golang来生成,我们知道以太坊的账户私钥是放在keystore文件中的,是一段json,并且创建的时候可以设置密码。跟比特币的wallet.dat文件是一样的意思,不见哪一样,你的资产就永远留在区块链网络中,再也无法找回。
  • 下面我们用代码创建两个以太坊账户。
  1. import (
  2. "github.com/ethereum/go-ethereum/accounts/keystore"
  3. )
  4. ks := keystore.NewKeyStore("/", keystore.StandardScryptN, keystore.StandardScryptP)
  5. address, _ := ks.NewAccount("password")
  6. account, err := ks.Export(address, "password", "password")
  7. if err != nil {
  8. panic(err)
  9. }
  • 从上面的代码我们可以看到,创建了一个以太坊的账户,并且密码设置为password,并导出。最终account变量就是账户的私钥,是一段json文本。
  • 通过address变量,我们可以获得账户的地址。如 address.Address.Hex()

生成代币文件

  • 打开 cd $GOPATH/src/github.com/ethereum/go-ethereum/cmd/abigen 你能看到main.go文件
  • 执行 go build main.go,会在目录下生成一个main的二进制文件。

  • 将以下的json 保存为token.abi,并放在当前目录下。

  1. [{"constant":true,"inputs":[],"name":"name","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"stop","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"guy","type":"address"},{"name":"wad","type":"uint256"}],"name":"approve","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"owner_","type":"address"}],"name":"setOwner","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transferFrom","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint128"}],"name":"push","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"name_","type":"bytes32"}],"name":"setName","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"mint","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"}],"name":"balanceOf","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"stopped","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"authority_","type":"address"}],"name":"setAuthority","outputs":[],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"src","type":"address"},{"name":"wad","type":"uint128"}],"name":"pull","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"wad","type":"uint128"}],"name":"burn","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"name":"","type":"bytes32"}],"payable":false,"type":"function"},{"constant":false,"inputs":[{"name":"dst","type":"address"},{"name":"wad","type":"uint256"}],"name":"transfer","outputs":[{"name":"","type":"bool"}],"payable":false,"type":"function"},{"constant":false,"inputs":[],"name":"start","outputs":[],"payable":false,"type":"function"},{"constant":true,"inputs":[],"name":"authority","outputs":[{"name":"","type":"address"}],"payable":false,"type":"function"},{"constant":true,"inputs":[{"name":"src","type":"address"},{"name":"guy","type":"address"}],"name":"allowance","outputs":[{"name":"","type":"uint256"}],"payable":false,"type":"function"},{"inputs":[{"name":"symbol_","type":"bytes32"}],"payable":false,"type":"constructor"},{"anonymous":true,"inputs":[{"indexed":true,"name":"sig","type":"bytes4"},{"indexed":true,"name":"guy","type":"address"},{"indexed":true,"name":"foo","type":"bytes32"},{"indexed":true,"name":"bar","type":"bytes32"},{"indexed":false,"name":"wad","type":"uint256"},{"indexed":false,"name":"fax","type":"bytes"}],"name":"LogNote","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"authority","type":"address"}],"name":"LogSetAuthority","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"}],"name":"LogSetOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"from","type":"address"},{"indexed":true,"name":"to","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"name":"owner","type":"address"},{"indexed":true,"name":"spender","type":"address"},{"indexed":false,"name":"value","type":"uint256"}],"name":"Approval","type":"event"}]

  

  • 执行命令 ./main --abi token.abi --pkg main --type Token --out token.go

  • 我们可以看到目录下生成了一个token.go文件。大功告成。

开始转账

  • 首先就把上一步生成的token.go拖入项目中。
  1. import (
  2. "github.com/ethereum/go-ethereum/accounts/abi/bind"
  3. )
  4. //首先导入上面生成的账户密钥(json)和密码
  5. auth, err := bind.NewTransactor(strings.NewReader("json"), "password")
  6. //这句用的是生成的token.go里面的方法
  7. //client变量是我们第一步连接以太坊rpc节点的时候创建的
  8. //contractAddress 是代币地址,比如eos 的地址是0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0
  9. //那么我们转账针对的就是账户里的eos代币
  10. //具体看这里 https://etherscan.io/token/0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0
  11. token, err := NewToken(common.HexToAddress("0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0"), client)
  12. if err != nil {
  13. panic(err)
  14. }
  15. //每个代币都会有相应的位数,例如eos是18位,那么我们转账的时候,需要在金额后面加18个0
  16. decimal, err := token.Decimals(nil)
  17. if err != nil {
  18. panic(err)
  19. }
  20. //这是处理位数的代码段
  21. tenDecimal := big.NewFloat(math.Pow(10, float64(decimal)))
  22. convertAmount, _ := new(big.Float).Mul(tenDecimal, amount).Int(&big.Int{})
  23. //然后就可以转账到你需要接受的账户上了
  24. //toAddress 是接受eos的账户地址
  25. txs, err := token.Transfer(auth, common.HexToAddress(toAddress), convertAmount)

  到此转账就成功了。

https://golang.org/src/go/token/token.go

里面还有很多其他的方法

golang学习笔记19 用Golang实现以太坊代币转账的更多相关文章

  1. 创建自己的加密货币MNC——以太坊代币(二)

    创建一个基于以太坊平台的分红币MNC,根据持有的代币数量,进行分红的算法.github地址: https://github.com/lxr1907/MNC 1.使用以太坊根据比例换购token MNC ...

  2. usdt钱包对接,usdt 对接交易平台,usdtapi,以太坊对接,以太坊代币对接

    usdt钱包对接,usdt 对接交易平台,usdtapi,以太坊对接,以太坊代币对接 自动充提币接口开发. 可对接:商城系统,游戏APP,交易平台,网站,各类APP -实现自动充提,查询,上链等功能接 ...

  3. 以太坊代币,USDT归集流程图

    1.用户充值 600 代币 (网站小助手会及时监听到用户的充值信息,并回调给用户填写的URL地址) 2.会员转账600代币,属于大额转账,开始触发系统的自动汇集程序 注:这里系统检测到会员的地址并没有 ...

  4. 科普贴 | 以太坊代币钱包MyEtherWallet使用教程,一步步教你玩转MEW

    MyEtherWallet 是一个以太坊的网页钱包,使用非常简单,打开网页就可以使用,源代码开源,不会在服务器上存储用户的钱包信息如私钥和密码.支持 Ledger Wallet.TREZOR 等硬件钱 ...

  5. 创建自己的区块链合约java版web3接口——以太坊代币(四)

    texas-web3j-solidity项目是一个java版本的,使用web3j包和eth网络交互的小程序. 主要实现了以下功能: 1.发布合约 2.发起转账 3.查询交易 4.调用智能合约方法 te ...

  6. 创建自己的区块链游戏SLOT——以太坊代币(三)

    一个以太坊合约版本的轮盘游戏,向合约转账ETH,有几率获得3,5,10,100倍奖励 合约地址:0x53DA598E70a1505Ad95cBF17fc5DCA0d2c51174b 捐赠ETH地址:0 ...

  7. golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题

    golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题 下面这个程序运行的能num结果是什么? package main import ( "fmt" " ...

  8. golang学习笔记18 用go语言编写移动端sdk和app开发gomobile

    golang学习笔记18 用go语言编写移动端sdk和app开发gomobile gomobile的使用-用go语言编写移动端sdk和app开发https://blog.csdn.net/u01249 ...

  9. golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍

    golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍 go语言爬虫框架:gocolly/colly,goquery,colly,chrom ...

随机推荐

  1. JavaScript学习(六)

    这里要注意: 1.num为NaN(因为str的开头不是数字) 2.NaN和NaN是不等的 3.NaN也是number.

  2. 认识程序的执行:从高级语言到二进制,以java为例

    java 高级编程语言,面向对象*.java是源码文件*.class是字节码文件,一种中间文件. JDK包含的基本组件包括: javac – 编译器,将源程序转成字节码 jar – 打包工具,将相关的 ...

  3. (1.15)mysql锁问题之InnoDB锁

    关键词:innodb锁,mysql锁 概要: 1.事务的隔离级别 2.InnoDB锁争用 3.innodb锁 [3.1]innodb的行锁模式及加锁方法 其实,默认情况下,mysql 的 select ...

  4. C# 线程池ThreadPool的用法简析

    https://blog.csdn.net/smooth_tailor/article/details/52460566 什么是线程池?为什么要用线程池?怎么用线程池? 1. 什么是线程池? .NET ...

  5. List与Array互相转换

    List转换为Array可以这样处理: ArrayList<String> list=new ArrayList<String>(); String[] strings = n ...

  6. Python中常用的模块

    模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

  7. css实现右侧固定宽度,左侧宽度自适应

    https://blog.csdn.net/qq_22889599/article/details/78414040 反过来也可以:左侧宽度固定,右侧自适应.不管是左是右,反正就是一边宽度固定,一边宽 ...

  8. [vue]data数据属性及ref获取dom

    data项的定义 this.$refs获取dom 获取不到数据 这样中转下才ok 小结: data里不能用this.$ref. 另外使用visjs时候 view-source:http://visjs ...

  9. c#中取整和取余

    "%"为取余. "/"号整型运算是取整,浮点运算时为除法运算.如54/10结果为5,54.0/10.0结果为5.4.而且取整时不进行四舍五入只取整数部分,如54 ...

  10. jupyter 快捷键

    Jupyter Notebook 的快捷键 Jupyter Notebook 有两种键盘输入模式.编辑模式,允许你往单元中键入代码或文本:这时的单元框线是绿色的.命令模式,键盘输入运行程序命令:这时的 ...