2017年區塊鏈火爆了整個互聯網金融圈,特別是ico的出現,讓不少人開始認識了數字貨幣。咱們知道以太坊(Ethereum)是目前最受歡迎的數字貨幣和區塊鏈系統,而eth每一個已經達到了2000+RMB。我記得剛認識以太坊的時候,是三十多一枚。php
contract ERC20 {
function totalSupply() constant returns (uint totalSupply);
function balanceOf(address _owner) constant returns (uint balance);
function transfer(address _to, uint _value) returns (bool success);
function transferFrom(address _from, address _to, uint _value) returns (bool success);
function approve(address _spender, uint _value) returns (bool success);
function allowance(address _owner, address _spender) constant returns (uint remaining);
event Transfer(address indexed _from, address indexed _to, uint _value);
event Approval(address indexed _owner, address indexed _spender, uint _value);
}複製代碼
智能合約代碼是運行在以太坊智能合約虛擬機中的。有興趣的同窗,能夠學習一下。附上文檔:solidity.readthedocs.io/en/latest/i…html
咱們看到上面那段相似golang中interface的代碼,裏面分別包含了總量、餘額、轉帳等方法。咱們今天重點講的其實就是用golang來實現transfer、transferFrom方法。git
8545
,我使用默認端口,後面咱們都用http://127.0.0.1:8545
做爲咱們的rpc鏈接。go get github.com/ethereum/go-ethereum
cd $GOPATH/src/github.com/ethereum/go-ethereum
import (
"github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/ethclient"
)
rpcDial, err := rpc.Dial("http://127.0.0.1:8545")
if err != nil {
panic(err);
}
client := ethclient.NewClient(rpcDial)複製代碼
import (
"github.com/ethereum/go-ethereum/accounts/keystore"
)
ks := keystore.NewKeyStore("/", keystore.StandardScryptN, keystore.StandardScryptP)
address, _ := ks.NewAccount("password")
account, err := ks.Export(address, "password", "password")
if err != nil {
panic(err)
}複製代碼
password
,並導出。最終account
變量就是帳戶的私鑰,是一段json文本。咱們能夠看看它大概長什麼樣。address
變量,咱們能夠得到帳戶的地址。好比這樣 address.Address.Hex()
{"address":"41e2f6a4eb0e61f627207ec4a3f7098388174368","crypto":{"cipher":"aes-128-ctr","ciphertext"
:"c0b10f9a3ca83837de83d38ca95bef200170d97e818f15bbc35642b6076c4a16",
"cipherparams":{"iv":"e46c3f2c76b35eedd7b065677faf6927"},
"kdf":"scrypt",
"kdfparams":
{"dklen":32,"n":262144,"p":1,"r":8,"salt"
:"05c8493a6a8518451c18ac05785e6c60507d906b130ee859e99804f0df90b63d"},
"mac"
:"62f52d9c4a078765b496cf76ed50634199c509e2d6e91106e24276d51124b971"}
,"id"
:"6c00339c-773b-4862-bb61-3a51a6f671ee",
"version":3}複製代碼
cd $GOPATH/src/github.com/ethereum/go-ethereum/cmd/abigen
你能看到main.go文件執行 go build main.go
,會在目錄下生成一個main
的二進制文件。github
將如下的json 保存爲token.abi,並放在當前目錄下。golang
[{"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
json
咱們能夠看到目錄下生成了一個token.go
文件。大功告成。服務器
token.go
拖入項目中。import (
"github.com/ethereum/go-ethereum/accounts/abi/bind"
)
//首先導入上面生成的帳戶密鑰(json)和密碼
auth, err := bind.NewTransactor(strings.NewReader("json"), "password")
//這句用的是生成的token.go裏面的方法
//client變量是咱們第一步鏈接以太坊rpc節點的時候建立的
//contractAddress 是代幣地址,好比eos 的地址是0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0
//那麼咱們轉帳針對的就是帳戶裏的eos代幣
//具體看這裏 https://etherscan.io/token/0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0
token, err := NewToken(common.HexToAddress("0x86fa049857e0209aa7d9e616f7eb3b3b78ecfdb0"), client)
if err != nil {
panic(err)
}
//每一個代幣都會有相應的位數,例如eos是18位,那麼咱們轉帳的時候,須要在金額後面加18個0
decimal, err := token.Decimals(nil)
if err != nil {
panic(err)
}
//這是處理位數的代碼段
tenDecimal := big.NewFloat(math.Pow(10, float64(decimal)))
convertAmount, _ := new(big.Float).Mul(tenDecimal, amount).Int(&big.Int{})
//而後就能夠轉帳到你須要接受的帳戶上了
//toAddress 是接受eos的帳戶地址
txs, err := token.Transfer(auth, common.HexToAddress(toAddress), convertAmount)複製代碼