dptrmt4366 2017-02-28 23:06
浏览 793

如何从Go调用以太坊合约?

I've tried to follow the go-ethereum guide for this but it seems out of date. I've tried looking around for a web3 library in Go but everything tries to point back to "use geth."

From Go, how do I call a contract in the Ethereum block chain? How different would it be if I'm targeting testnet or testrpc?

  • 写回答

1条回答 默认 最新

  • dongshuofu0039 2018-05-28 19:32
    关注

    Here's a simple example of how you can interact with a smart contract in Go. Assuming you have solc and abigen installed.

    solc --abi Store.sol > Store.abi
    solc --bin Store.sol > Store.bin
    abigen --bin=Store.bin --abi=Store.abi --pkg=store --out=Store.go
    

    Store.sol

    pragma solidity ^0.4.24;
    
    contract Store {
      event ItemSet(bytes32 key, bytes32 value);
    
      string public version;
      mapping (bytes32 => bytes32) public items;
    
      constructor(string _version) public {
        version = _version;
      }
    
      function setItem(bytes32 key, bytes32 value) external {
        items[key] = value;
        emit ItemSet(key, value);
      }
    }
    

    main.go

    package main
    
    import (
        "context"
        "crypto/ecdsa"
        "fmt"
        "log"
        "math/big"
    
        "github.com/ethereum/go-ethereum/accounts/abi/bind"
        "github.com/ethereum/go-ethereum/common"
        "github.com/ethereum/go-ethereum/crypto"
        "github.com/ethereum/go-ethereum/ethclient"
    
        store "./contracts" // for demo
    )
    
    func main() {
        client, err := ethclient.Dial("https://rinkeby.infura.io")
        if err != nil {
            log.Fatal(err)
        }
    
        privateKey, err := crypto.HexToECDSA("fad9c8855b740a0b7ed4c221dbad0f33a83a49cad6b3fe8d5817ac83d38b6a19")
        if err != nil {
            log.Fatal(err)
        }
    
        publicKey := privateKey.Public()
        publicKeyECDSA, ok := publicKey.(*ecdsa.PublicKey)
        if !ok {
            log.Fatal("error casting public key to ECDSA")
        }
    
        fromAddress := crypto.PubkeyToAddress(*publicKeyECDSA)
        nonce, err := client.PendingNonceAt(context.Background(), fromAddress)
        if err != nil {
            log.Fatal(err)
        }
    
        gasPrice, err := client.SuggestGasPrice(context.Background())
        if err != nil {
            log.Fatal(err)
        }
    
        auth := bind.NewKeyedTransactor(privateKey)
        auth.Nonce = big.NewInt(int64(nonce))
        auth.Value = big.NewInt(0)     // in wei
        auth.GasLimit = uint64(300000) // in units
        auth.GasPrice = gasPrice
    
        address := common.HexToAddress("0x147B8eb97fD247D06C4006D269c90C1908Fb5D54")
        instance, err := store.NewStore(address, client)
        if err != nil {
            log.Fatal(err)
        }
    
        key := [32]byte{}
        value := [32]byte{}
        copy(key[:], []byte("foo"))
        copy(value[:], []byte("bar"))
    
        tx, err := instance.SetItem(auth, key, value)
        if err != nil {
            log.Fatal(err)
        }
    
        fmt.Printf("tx sent: %s", tx.Hash().Hex()) // tx sent: 0x8d490e535678e9a24360e955d75b27ad307bdfb97a1dca51d0f3035dcee3e870
    
        result, err := instance.Items(&bind.CallOpts{}, key)
        if err != nil {
            log.Fatal(err)
        }
    
        fmt.Println(string(result[:])) // "bar"
    }
    

    For more examples, check out the Ethereum Development with Go book.

    评论

报告相同问题?

悬赏问题

  • ¥15 stable diffusion
  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算