github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/mobile/bind.go (about) 1 2 //<developer> 3 // <name>linapex 曹一峰</name> 4 // <email>linapex@163.com</email> 5 // <wx>superexc</wx> 6 // <qqgroup>128148617</qqgroup> 7 // <url>https://jsq.ink</url> 8 // <role>pku engineer</role> 9 // <date>2019-03-16 12:09:43</date> 10 //</624342653282029568> 11 12 13 //包含绑定包中的所有包装。 14 15 package geth 16 17 import ( 18 "math/big" 19 "strings" 20 21 "github.com/ethereum/go-ethereum/accounts/abi" 22 "github.com/ethereum/go-ethereum/accounts/abi/bind" 23 "github.com/ethereum/go-ethereum/common" 24 "github.com/ethereum/go-ethereum/core/types" 25 ) 26 27 //签名者是一个接口,当合同要求 28 //提交前签署事务的方法。 29 type Signer interface { 30 Sign(*Address, *Transaction) (tx *Transaction, _ error) 31 } 32 33 type signer struct { 34 sign bind.SignerFn 35 } 36 37 func (s *signer) Sign(addr *Address, unsignedTx *Transaction) (signedTx *Transaction, _ error) { 38 sig, err := s.sign(types.HomesteadSigner{}, addr.address, unsignedTx.tx) 39 if err != nil { 40 return nil, err 41 } 42 return &Transaction{sig}, nil 43 } 44 45 //Callopts是对合同调用请求进行微调的选项集合。 46 type CallOpts struct { 47 opts bind.CallOpts 48 } 49 50 //newcallopts为合同调用创建新的选项集。 51 func NewCallOpts() *CallOpts { 52 return new(CallOpts) 53 } 54 55 func (opts *CallOpts) IsPending() bool { return opts.opts.Pending } 56 /*c(opts*callopts)getgaslimit()int64返回0/*todo(karalabe)*/ 57 58 //没有身份保护,getContext无法可靠实现(https://github.com/golang/go/issues/16876) 59 即使是这样,将GO上下文的细微部分解压缩到Java也是很困难的。 60 //func(opts*callopts)getContext()*context返回&context opts.opts.context 61 62 func(opts*callopts)setpending(挂起bool)opts.opts.pending=挂起 63 func(opts*callopts)setgaslimit(limit int64)/*todo(karalabe)*/ } 64 65 func (opts *CallOpts) SetContext(context *Context) { opts.opts.Context = context.context } 66 67 //TransactioOpts是创建 68 //有效的以太坊事务。 69 type TransactOpts struct { 70 opts bind.TransactOpts 71 } 72 73 func (opts *TransactOpts) GetFrom() *Address { return &Address{opts.opts.From} } 74 func (opts *TransactOpts) GetNonce() int64 { return opts.opts.Nonce.Int64() } 75 func (opts *TransactOpts) GetValue() *BigInt { return &BigInt{opts.opts.Value} } 76 func (opts *TransactOpts) GetGasPrice() *BigInt { return &BigInt{opts.opts.GasPrice} } 77 func (opts *TransactOpts) GetGasLimit() int64 { return int64(opts.opts.GasLimit) } 78 79 //没有身份保护,getsigner无法可靠实现(https://github.com/golang/go/issues/16876) 80 //func(opts*transactioopts)getsigner()签名者返回&签名者opts.opts.signer 81 82 //没有身份保护,getContext无法可靠实现(https://github.com/golang/go/issues/16876) 83 //即使这样,将GO上下文的细微部分解压缩到Java也是很困难的。 84 //func(opts*transactionopts)getContext()*context返回&context opts.opts.context 85 86 func (opts *TransactOpts) SetFrom(from *Address) { opts.opts.From = from.address } 87 func (opts *TransactOpts) SetNonce(nonce int64) { opts.opts.Nonce = big.NewInt(nonce) } 88 func (opts *TransactOpts) SetSigner(s Signer) { 89 opts.opts.Signer = func(signer types.Signer, addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 90 sig, err := s.Sign(&Address{addr}, &Transaction{tx}) 91 if err != nil { 92 return nil, err 93 } 94 return sig.tx, nil 95 } 96 } 97 func (opts *TransactOpts) SetValue(value *BigInt) { opts.opts.Value = value.bigint } 98 func (opts *TransactOpts) SetGasPrice(price *BigInt) { opts.opts.GasPrice = price.bigint } 99 func (opts *TransactOpts) SetGasLimit(limit int64) { opts.opts.GasLimit = uint64(limit) } 100 func (opts *TransactOpts) SetContext(context *Context) { opts.opts.Context = context.context } 101 102 //BoundContract是反映在 103 //以太坊网络。它包含由 104 //要操作的更高级别合同绑定。 105 type BoundContract struct { 106 contract *bind.BoundContract 107 address common.Address 108 deployer *types.Transaction 109 } 110 111 //DeployContract将合同部署到以太坊区块链上,并绑定 112 //带有包装的部署地址。 113 func DeployContract(opts *TransactOpts, abiJSON string, bytecode []byte, client *EthereumClient, args *Interfaces) (contract *BoundContract, _ error) { 114 //将合同部署到网络 115 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 116 if err != nil { 117 return nil, err 118 } 119 addr, tx, bound, err := bind.DeployContract(&opts.opts, parsed, common.CopyBytes(bytecode), client.client, args.objects...) 120 if err != nil { 121 return nil, err 122 } 123 return &BoundContract{ 124 contract: bound, 125 address: addr, 126 deployer: tx, 127 }, nil 128 } 129 130 //bindcontact创建一个低级合同接口,通过该接口调用和 131 //交易可以通过。 132 func BindContract(address *Address, abiJSON string, client *EthereumClient) (contract *BoundContract, _ error) { 133 parsed, err := abi.JSON(strings.NewReader(abiJSON)) 134 if err != nil { 135 return nil, err 136 } 137 return &BoundContract{ 138 contract: bind.NewBoundContract(address.address, parsed, client.client, client.client, client.client), 139 address: address.address, 140 }, nil 141 } 142 143 func (c *BoundContract) GetAddress() *Address { return &Address{c.address} } 144 func (c *BoundContract) GetDeployer() *Transaction { 145 if c.deployer == nil { 146 return nil 147 } 148 return &Transaction{c.deployer} 149 } 150 151 //调用调用(常量)contract方法,参数作为输入值,并且 152 //将输出设置为结果。 153 func (c *BoundContract) Call(opts *CallOpts, out *Interfaces, method string, args *Interfaces) error { 154 if len(out.objects) == 1 { 155 result := out.objects[0] 156 if err := c.contract.Call(&opts.opts, result, method, args.objects...); err != nil { 157 return err 158 } 159 out.objects[0] = result 160 } else { 161 results := make([]interface{}, len(out.objects)) 162 copy(results, out.objects) 163 if err := c.contract.Call(&opts.opts, &results, method, args.objects...); err != nil { 164 return err 165 } 166 copy(out.objects, results) 167 } 168 return nil 169 } 170 171 //Transact使用参数作为输入值调用(付费)Contract方法。 172 func (c *BoundContract) Transact(opts *TransactOpts, method string, args *Interfaces) (tx *Transaction, _ error) { 173 rawTx, err := c.contract.Transact(&opts.opts, method, args.objects...) 174 if err != nil { 175 return nil, err 176 } 177 return &Transaction{rawTx}, nil 178 } 179 180 //转账启动普通交易以将资金转移到合同,调用 181 //它的默认方法(如果有)。 182 func (c *BoundContract) Transfer(opts *TransactOpts) (tx *Transaction, _ error) { 183 rawTx, err := c.contract.Transfer(&opts.opts) 184 if err != nil { 185 return nil, err 186 } 187 return &Transaction{rawTx}, nil 188 } 189