首页 文章

在Go - contract函数调用中构建原始的以太坊交易

提问于
浏览
1

我正在修改go-ethereum,以便能够使用我们正在创建的令牌处理合并挖掘 . 因此,每当一个矿工拥有我们的geth版本运行和挖掘时,如果他们找到一个区块,他们将通过我们的 Contract 收到X金额的令牌 .

该 Contract 旨在处理给区块矿工的奖励 . 我只需要修改go-ethereum来处理在 Contract 中添加调用奖励函数的事务并在提交块之前将其添加到tx池 .

在go-ethereum中,我在miner包中添加了一个新的go文件 token_claim.go . 查看miner.go文件,似乎我需要在密封块之前添加此代码以在 /go-ethereum-1.6.7/miner/worker.go 左右的 /go-ethereum-1.6.7/miner/worker.go 内 Build 一个奖励声明交易的标志 .

有人可以提供在Go中调用 Contract 函数构建原始事务的示例 . 我有abi,字节码和 Contract 地址 .

谢谢

1 回答

  • 0

    这是一个简单的例子,说明如何在Go中与智能合约进行交互 . 假设你安装了 solcabigen .

    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"
    }
    

    有关更多示例,请查看Ethereum Development with Go book .

相关问题