github.com/linapex/ethereum-dpos-chinese@v0.0.0-20190316121959-b78b3a4a1ece/internal/ethapi/api.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:40</date> 10 //</624342641198239744> 11 12 13 package ethapi 14 15 import ( 16 "bytes" 17 "context" 18 "errors" 19 "fmt" 20 "math/big" 21 "strings" 22 "time" 23 24 "github.com/davecgh/go-spew/spew" 25 "github.com/ethereum/go-ethereum/accounts" 26 "github.com/ethereum/go-ethereum/accounts/keystore" 27 "github.com/ethereum/go-ethereum/common" 28 "github.com/ethereum/go-ethereum/common/hexutil" 29 "github.com/ethereum/go-ethereum/common/math" 30 "github.com/ethereum/go-ethereum/consensus/ethash" 31 "github.com/ethereum/go-ethereum/core" 32 "github.com/ethereum/go-ethereum/core/rawdb" 33 "github.com/ethereum/go-ethereum/core/types" 34 "github.com/ethereum/go-ethereum/core/vm" 35 "github.com/ethereum/go-ethereum/crypto" 36 "github.com/ethereum/go-ethereum/log" 37 "github.com/ethereum/go-ethereum/p2p" 38 "github.com/ethereum/go-ethereum/params" 39 "github.com/ethereum/go-ethereum/rlp" 40 "github.com/ethereum/go-ethereum/rpc" 41 "github.com/syndtr/goleveldb/leveldb" 42 "github.com/syndtr/goleveldb/leveldb/util" 43 ) 44 45 const ( 46 defaultGasPrice = 50 * params.Shannon 47 ) 48 49 //PublicEthereumAPI提供一个API来访问与以太坊相关的信息。 50 //它只提供对任何人都可以自由使用的公共数据进行操作的方法。 51 type PublicEthereumAPI struct { 52 b Backend 53 } 54 55 //NewPublicEthereumAPI创建新的Ethereum协议API。 56 func NewPublicEthereumAPI(b Backend) *PublicEthereumAPI { 57 return &PublicEthereumAPI{b} 58 } 59 60 //加斯普赖斯返回了一个天然气价格的建议。 61 func (s *PublicEthereumAPI) GasPrice(ctx context.Context) (*hexutil.Big, error) { 62 price, err := s.b.SuggestPrice(ctx) 63 return (*hexutil.Big)(price), err 64 } 65 66 //ProtocolVersion返回此节点支持的当前以太坊协议版本 67 func (s *PublicEthereumAPI) ProtocolVersion() hexutil.Uint { 68 return hexutil.Uint(s.b.ProtocolVersion()) 69 } 70 71 //如果节点当前未与网络同步,则同步将返回false。它可以是最新的,也可以没有。 72 //但它收到了梨的最新数据块头。如果正在同步: 73 //-startingblock:此节点开始同步的块号 74 //-currentblock:此节点当前导入的块号 75 //-highest block:此节点从对等方接收到的最高块头的块号 76 //-pulledstates:到目前为止处理的状态条目数 77 //-knownstates:仍需要提取的已知状态条目数 78 func (s *PublicEthereumAPI) Syncing() (interface{}, error) { 79 progress := s.b.Downloader().Progress() 80 81 //如果同步已完成,则返回“未同步” 82 if progress.CurrentBlock >= progress.HighestBlock { 83 return false, nil 84 } 85 //否则收集块同步状态 86 return map[string]interface{}{ 87 "startingBlock": hexutil.Uint64(progress.StartingBlock), 88 "currentBlock": hexutil.Uint64(progress.CurrentBlock), 89 "highestBlock": hexutil.Uint64(progress.HighestBlock), 90 "pulledStates": hexutil.Uint64(progress.PulledStates), 91 "knownStates": hexutil.Uint64(progress.KnownStates), 92 }, nil 93 } 94 95 //publicTxPoolapi为事务池提供和API。它只对非机密数据进行操作。 96 type PublicTxPoolAPI struct { 97 b Backend 98 } 99 100 //newpublicTxPoolapi创建一个新的TxPool服务,提供有关事务池的信息。 101 func NewPublicTxPoolAPI(b Backend) *PublicTxPoolAPI { 102 return &PublicTxPoolAPI{b} 103 } 104 105 //Content返回事务池中包含的事务。 106 func (s *PublicTxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { 107 content := map[string]map[string]map[string]*RPCTransaction{ 108 "pending": make(map[string]map[string]*RPCTransaction), 109 "queued": make(map[string]map[string]*RPCTransaction), 110 } 111 pending, queue := s.b.TxPoolContent() 112 113 //平摊未决交易 114 for account, txs := range pending { 115 dump := make(map[string]*RPCTransaction) 116 for _, tx := range txs { 117 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) 118 } 119 content["pending"][account.Hex()] = dump 120 } 121 //扁平排队的事务 122 for account, txs := range queue { 123 dump := make(map[string]*RPCTransaction) 124 for _, tx := range txs { 125 dump[fmt.Sprintf("%d", tx.Nonce())] = newRPCPendingTransaction(tx) 126 } 127 content["queued"][account.Hex()] = dump 128 } 129 return content 130 } 131 132 //status返回池中挂起和排队的事务数。 133 func (s *PublicTxPoolAPI) Status() map[string]hexutil.Uint { 134 pending, queue := s.b.Stats() 135 return map[string]hexutil.Uint{ 136 "pending": hexutil.Uint(pending), 137 "queued": hexutil.Uint(queue), 138 } 139 } 140 141 //inspect检索事务池的内容并将其扁平化为 142 //易于检查的列表。 143 func (s *PublicTxPoolAPI) Inspect() map[string]map[string]map[string]string { 144 content := map[string]map[string]map[string]string{ 145 "pending": make(map[string]map[string]string), 146 "queued": make(map[string]map[string]string), 147 } 148 pending, queue := s.b.TxPoolContent() 149 150 //定义格式化程序以将事务扁平化为字符串 151 var format = func(tx *types.Transaction) string { 152 if to := tx.To(); to != nil { 153 return fmt.Sprintf("%s: %v wei + %v gas × %v wei", tx.To().Hex(), tx.Value(), tx.Gas(), tx.GasPrice()) 154 } 155 return fmt.Sprintf("contract creation: %v wei + %v gas × %v wei", tx.Value(), tx.Gas(), tx.GasPrice()) 156 } 157 //平摊未决交易 158 for account, txs := range pending { 159 dump := make(map[string]string) 160 for _, tx := range txs { 161 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 162 } 163 content["pending"][account.Hex()] = dump 164 } 165 //扁平排队的事务 166 for account, txs := range queue { 167 dump := make(map[string]string) 168 for _, tx := range txs { 169 dump[fmt.Sprintf("%d", tx.Nonce())] = format(tx) 170 } 171 content["queued"][account.Hex()] = dump 172 } 173 return content 174 } 175 176 //PublicAccountAPI提供了一个API,用于访问此节点管理的帐户。 177 //它只提供可以检索帐户的方法。 178 type PublicAccountAPI struct { 179 am *accounts.Manager 180 } 181 182 //我创建了一个新的公共会计。 183 func NewPublicAccountAPI(am *accounts.Manager) *PublicAccountAPI { 184 return &PublicAccountAPI{am: am} 185 } 186 187 //帐户返回此节点管理的帐户集合 188 func (s *PublicAccountAPI) Accounts() []common.Address { 189 addresses := make([]common.Address, 0) //如果为空,则返回[]而不是零 190 for _, wallet := range s.am.Wallets() { 191 for _, account := range wallet.Accounts() { 192 addresses = append(addresses, account.Address) 193 } 194 } 195 return addresses 196 } 197 198 //privateaccountapi提供了访问此节点管理的帐户的API。 199 //它提供创建(取消)锁定列表帐户的方法。有些方法可以接受 200 //密码,因此默认情况下被视为私有密码。 201 type PrivateAccountAPI struct { 202 am *accounts.Manager 203 nonceLock *AddrLocker 204 b Backend 205 } 206 207 //new privateaccountapi创建新的privateaccountapi。 208 func NewPrivateAccountAPI(b Backend, nonceLock *AddrLocker) *PrivateAccountAPI { 209 return &PrivateAccountAPI{ 210 am: b.AccountManager(), 211 nonceLock: nonceLock, 212 b: b, 213 } 214 } 215 216 //list accounts将返回此节点管理的帐户的地址列表。 217 func (s *PrivateAccountAPI) ListAccounts() []common.Address { 218 addresses := make([]common.Address, 0) //如果为空,则返回[]而不是零 219 for _, wallet := range s.am.Wallets() { 220 for _, account := range wallet.Accounts() { 221 addresses = append(addresses, account.Address) 222 } 223 } 224 return addresses 225 } 226 227 //rawwallet是一个帐户.wallet接口的JSON表示,其 228 //将数据内容提取到普通字段中。 229 type rawWallet struct { 230 URL string `json:"url"` 231 Status string `json:"status"` 232 Failure string `json:"failure,omitempty"` 233 Accounts []accounts.Account `json:"accounts,omitempty"` 234 } 235 236 //list wallets将返回此节点管理的钱包列表。 237 func (s *PrivateAccountAPI) ListWallets() []rawWallet { 238 wallets := make([]rawWallet, 0) //如果为空,则返回[]而不是零 239 for _, wallet := range s.am.Wallets() { 240 status, failure := wallet.Status() 241 242 raw := rawWallet{ 243 URL: wallet.URL().String(), 244 Status: status, 245 Accounts: wallet.Accounts(), 246 } 247 if failure != nil { 248 raw.Failure = failure.Error() 249 } 250 wallets = append(wallets, raw) 251 } 252 return wallets 253 } 254 255 //OpenWallet启动硬件钱包打开程序,建立USB 256 //连接并尝试通过提供的密码短语进行身份验证。注: 257 //该方法可能会返回需要第二次打开的额外挑战(例如 258 //Trezor针矩阵挑战)。 259 func (s *PrivateAccountAPI) OpenWallet(url string, passphrase *string) error { 260 wallet, err := s.am.Wallet(url) 261 if err != nil { 262 return err 263 } 264 pass := "" 265 if passphrase != nil { 266 pass = *passphrase 267 } 268 return wallet.Open(pass) 269 } 270 271 //DeriveAccount请求HD钱包派生一个新帐户,可以选择固定 272 //供以后再使用。 273 func (s *PrivateAccountAPI) DeriveAccount(url string, path string, pin *bool) (accounts.Account, error) { 274 wallet, err := s.am.Wallet(url) 275 if err != nil { 276 return accounts.Account{}, err 277 } 278 derivPath, err := accounts.ParseDerivationPath(path) 279 if err != nil { 280 return accounts.Account{}, err 281 } 282 if pin == nil { 283 pin = new(bool) 284 } 285 return wallet.Derive(derivPath, *pin) 286 } 287 288 //new account将创建一个新帐户并返回新帐户的地址。 289 func (s *PrivateAccountAPI) NewAccount(password string) (common.Address, error) { 290 acc, err := fetchKeystore(s.am).NewAccount(password) 291 if err == nil { 292 return acc.Address, nil 293 } 294 return common.Address{}, err 295 } 296 297 //fetchkeystore从帐户管理器检索加密的密钥库。 298 func fetchKeystore(am *accounts.Manager) *keystore.KeyStore { 299 return am.Backends(keystore.KeyStoreType)[0].(*keystore.KeyStore) 300 } 301 302 //importrawkey将给定的十六进制编码的ecdsa密钥存储到密钥目录中, 303 //用密码短语加密。 304 func (s *PrivateAccountAPI) ImportRawKey(privkey string, password string) (common.Address, error) { 305 key, err := crypto.HexToECDSA(privkey) 306 if err != nil { 307 return common.Address{}, err 308 } 309 acc, err := fetchKeystore(s.am).ImportECDSA(key, password) 310 return acc.Address, err 311 } 312 313 //解锁帐户将解锁与给定地址关联的帐户 314 //持续时间秒的给定密码。如果持续时间为零,则使用 315 //默认为300秒。它返回帐户是否已解锁的指示。 316 func (s *PrivateAccountAPI) UnlockAccount(addr common.Address, password string, duration *uint64) (bool, error) { 317 const max = uint64(time.Duration(math.MaxInt64) / time.Second) 318 var d time.Duration 319 if duration == nil { 320 d = 300 * time.Second 321 } else if *duration > max { 322 return false, errors.New("unlock duration too large") 323 } else { 324 d = time.Duration(*duration) * time.Second 325 } 326 err := fetchKeystore(s.am).TimedUnlock(accounts.Account{Address: addr}, password, d) 327 return err == nil, err 328 } 329 330 //LockAccount解锁后将锁定与给定地址关联的帐户。 331 func (s *PrivateAccountAPI) LockAccount(addr common.Address) bool { 332 return fetchKeystore(s.am).Lock(addr) == nil 333 } 334 335 //signtransactions设置默认值并对给定事务进行签名 336 //注:如果适用,呼叫方需要确保保持非锁定状态。 337 //并在事务提交到Tx池后释放它 338 func (s *PrivateAccountAPI) signTransaction(ctx context.Context, args SendTxArgs, passwd string) (*types.Transaction, error) { 339 //查找包含请求签名者的钱包 340 account := accounts.Account{Address: args.From} 341 wallet, err := s.am.Find(account) 342 if err != nil { 343 return nil, err 344 } 345 //设置一些健全的默认值并在失败时终止 346 if err := args.setDefaults(ctx, s.b); err != nil { 347 return nil, err 348 } 349 //整理交易并用钱包签名 350 tx := args.toTransaction() 351 352 var chainID *big.Int 353 if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { 354 chainID = config.ChainID 355 } 356 return wallet.SignTxWithPassphrase(account, passwd, tx, chainID) 357 } 358 359 //sendTransaction将根据给定的参数和 360 //尝试使用与args.to关联的密钥对其进行签名。如果给定的密码不是 361 //能够解密失败的密钥。 362 func (s *PrivateAccountAPI) SendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 363 if args.Nonce == nil { 364 //在签名周围保持地址的互斥体,以防止同时分配 365 //对多个帐户使用同一个nonce。 366 s.nonceLock.LockAddr(args.From) 367 defer s.nonceLock.UnlockAddr(args.From) 368 } 369 signed, err := s.signTransaction(ctx, args, passwd) 370 if err != nil { 371 return common.Hash{}, err 372 } 373 return submitTransaction(ctx, s.b, signed) 374 } 375 376 //signTransaction将根据给定的参数和 377 //尝试使用与args.to关联的密钥对其进行签名。如果给定的密码不是 378 //能够解密失败的密钥。事务以RLP形式返回,而不是广播 379 //其他节点 380 func (s *PrivateAccountAPI) SignTransaction(ctx context.Context, args SendTxArgs, passwd string) (*SignTransactionResult, error) { 381 //不需要获取非CELSOCK互斥体,因为我们不会发送这个 382 //发送到事务池,但立即返回给用户 383 if args.Gas == nil { 384 return nil, fmt.Errorf("gas not specified") 385 } 386 if args.GasPrice == nil { 387 return nil, fmt.Errorf("gasPrice not specified") 388 } 389 if args.Nonce == nil { 390 return nil, fmt.Errorf("nonce not specified") 391 } 392 signed, err := s.signTransaction(ctx, args, passwd) 393 if err != nil { 394 return nil, err 395 } 396 data, err := rlp.EncodeToBytes(signed) 397 if err != nil { 398 return nil, err 399 } 400 return &SignTransactionResult{data, signed}, nil 401 } 402 403 //signhash是一个帮助函数,用于计算给定消息的哈希 404 //安全地用于计算签名。 405 // 406 //哈希被计算为 407 //keccak256(“\x19ethereum签名消息:\n”$消息长度$消息)。 408 // 409 //这将为已签名的消息提供上下文,并防止对事务进行签名。 410 func signHash(data []byte) []byte { 411 msg := fmt.Sprintf("\x19Ethereum Signed Message:\n%d%s", len(data), data) 412 return crypto.Keccak256([]byte(msg)) 413 } 414 415 //sign计算以太坊ECDSA签名: 416 //keccack256(“\x19ethereum签名消息:\n”+len(消息)+消息) 417 // 418 //注:生成的签名符合secp256k1曲线r、s和v值, 419 //由于遗产原因,V值将为27或28。 420 // 421 //用于计算签名的密钥用给定的密码解密。 422 // 423 //https://github.com/ethereum/go-ethereum/wiki/management-apis个人签名 424 func (s *PrivateAccountAPI) Sign(ctx context.Context, data hexutil.Bytes, addr common.Address, passwd string) (hexutil.Bytes, error) { 425 //查找包含请求签名者的钱包 426 account := accounts.Account{Address: addr} 427 428 wallet, err := s.b.AccountManager().Find(account) 429 if err != nil { 430 return nil, err 431 } 432 //集合用钱包签名数据 433 signature, err := wallet.SignHashWithPassphrase(account, passwd, signHash(data)) 434 if err != nil { 435 return nil, err 436 } 437 signature[64] += 27 //根据黄纸将V从0/1转换为27/28 438 return signature, nil 439 } 440 441 //ecrecover返回用于创建签名的帐户的地址。 442 //注意,此功能与ETH标志和个人标志兼容。因此,它恢复了 443 //地址: 444 //hash=keccak256(“\x19ethereum签名消息:\n”$消息长度$消息) 445 //addr=ecrecover(哈希,签名) 446 // 447 //注意,签名必须符合secp256k1曲线r、s和v值,其中 448 //由于遗留原因,V值必须是27或28。 449 // 450 //https://github.com/ethereum/go-ethereum/wiki/management-apis个人\u-ecrecover 451 func (s *PrivateAccountAPI) EcRecover(ctx context.Context, data, sig hexutil.Bytes) (common.Address, error) { 452 if len(sig) != 65 { 453 return common.Address{}, fmt.Errorf("signature must be 65 bytes long") 454 } 455 if sig[64] != 27 && sig[64] != 28 { 456 return common.Address{}, fmt.Errorf("invalid Ethereum signature (V is not 27 or 28)") 457 } 458 sig[64] -= 27 //将黄纸V从27/28转换为0/1 459 460 rpk, err := crypto.SigToPub(signHash(data), sig) 461 if err != nil { 462 return common.Address{}, err 463 } 464 return crypto.PubkeyToAddress(*rpk), nil 465 } 466 467 //SignandSendTransaction已重命名为SendTransaction。此方法已弃用 468 //并将在未来被移除。它的主要目标是给客户时间更新。 469 func (s *PrivateAccountAPI) SignAndSendTransaction(ctx context.Context, args SendTxArgs, passwd string) (common.Hash, error) { 470 return s.SendTransaction(ctx, args, passwd) 471 } 472 473 //PublicBlockChainAPI提供访问以太坊区块链的API。 474 //它只提供对任何人都可以自由使用的公共数据进行操作的方法。 475 type PublicBlockChainAPI struct { 476 b Backend 477 } 478 479 //NewPublicBlockChainAPI创建新的以太坊区块链API。 480 func NewPublicBlockChainAPI(b Backend) *PublicBlockChainAPI { 481 return &PublicBlockChainAPI{b} 482 } 483 484 //BlockNumber返回链头的块号。 485 func (s *PublicBlockChainAPI) BlockNumber() hexutil.Uint64 { 486 header, _ := s.b.HeaderByNumber(context.Background(), rpc.LatestBlockNumber) //最新的标题应始终可用 487 return hexutil.Uint64(header.Number.Uint64()) 488 } 489 490 //GetBalance返回给定地址在 491 //给定的块编号。rpc.latestBlockNumber和rpc.pendingBlockNumber元 492 //也允许使用块编号。 493 func (s *PublicBlockChainAPI) GetBalance(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Big, error) { 494 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 495 if state == nil || err != nil { 496 return nil, err 497 } 498 return (*hexutil.Big)(state.GetBalance(address)), state.Error() 499 } 500 501 //GetBlockByNumber返回请求的块。当blocknr为-1时,链头返回。当fulltx为真时,所有 502 //块中的事务将返回完整的详细信息,否则只返回事务哈希。 503 func (s *PublicBlockChainAPI) GetBlockByNumber(ctx context.Context, blockNr rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { 504 block, err := s.b.BlockByNumber(ctx, blockNr) 505 if block != nil { 506 response, err := s.rpcOutputBlock(block, true, fullTx) 507 if err == nil && blockNr == rpc.PendingBlockNumber { 508 //挂起的块需要去掉几个字段 509 for _, field := range []string{"hash", "nonce", "miner"} { 510 response[field] = nil 511 } 512 } 513 return response, err 514 } 515 return nil, err 516 } 517 518 //GetBlockByHash返回请求的块。当fulltx为true时,块中的所有事务都将全部返回 519 //详细信息,否则只返回事务哈希。 520 func (s *PublicBlockChainAPI) GetBlockByHash(ctx context.Context, blockHash common.Hash, fullTx bool) (map[string]interface{}, error) { 521 block, err := s.b.GetBlock(ctx, blockHash) 522 if block != nil { 523 return s.rpcOutputBlock(block, true, fullTx) 524 } 525 return nil, err 526 } 527 528 //GetUncleByBlockNumberAndIndex返回给定块哈希和索引的叔叔块。当fulltx为真时 529 //块中的所有事务都将返回完整的详细信息,否则只返回事务哈希。 530 func (s *PublicBlockChainAPI) GetUncleByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) (map[string]interface{}, error) { 531 block, err := s.b.BlockByNumber(ctx, blockNr) 532 if block != nil { 533 uncles := block.Uncles() 534 if index >= hexutil.Uint(len(uncles)) { 535 log.Debug("Requested uncle not found", "number", blockNr, "hash", block.Hash(), "index", index) 536 return nil, nil 537 } 538 block = types.NewBlockWithHeader(uncles[index]) 539 return s.rpcOutputBlock(block, false, false) 540 } 541 return nil, err 542 } 543 544 //GetUncleByBlockHashAndIndex返回给定块哈希和索引的叔叔块。当fulltx为真时 545 //块中的所有事务都将返回完整的详细信息,否则只返回事务哈希。 546 func (s *PublicBlockChainAPI) GetUncleByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) (map[string]interface{}, error) { 547 block, err := s.b.GetBlock(ctx, blockHash) 548 if block != nil { 549 uncles := block.Uncles() 550 if index >= hexutil.Uint(len(uncles)) { 551 log.Debug("Requested uncle not found", "number", block.Number(), "hash", blockHash, "index", index) 552 return nil, nil 553 } 554 block = types.NewBlockWithHeader(uncles[index]) 555 return s.rpcOutputBlock(block, false, false) 556 } 557 return nil, err 558 } 559 560 //GetUncleCountByBlockNumber返回给定块号的块中的叔叔数 561 func (s *PublicBlockChainAPI) GetUncleCountByBlockNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 562 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 563 n := hexutil.Uint(len(block.Uncles())) 564 return &n 565 } 566 return nil 567 } 568 569 //GetUncleCountByBlockHash返回给定块哈希的块中的叔叔数 570 func (s *PublicBlockChainAPI) GetUncleCountByBlockHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 571 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 572 n := hexutil.Uint(len(block.Uncles())) 573 return &n 574 } 575 return nil 576 } 577 578 //getcode返回给定块号状态下存储在给定地址的代码。 579 func (s *PublicBlockChainAPI) GetCode(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { 580 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 581 if state == nil || err != nil { 582 return nil, err 583 } 584 code := state.GetCode(address) 585 return code, state.Error() 586 } 587 588 //GetStorageAt返回给定地址、键和 589 //块号。The rpc.LatestBlockNumber and rpc.PendingBlockNumber meta block 590 //也允许使用数字。 591 func (s *PublicBlockChainAPI) GetStorageAt(ctx context.Context, address common.Address, key string, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { 592 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 593 if state == nil || err != nil { 594 return nil, err 595 } 596 res := state.GetState(address, common.HexToHash(key)) 597 return res[:], state.Error() 598 } 599 600 //callargs表示调用的参数。 601 type CallArgs struct { 602 From common.Address `json:"from"` 603 To *common.Address `json:"to"` 604 Gas hexutil.Uint64 `json:"gas"` 605 GasPrice hexutil.Big `json:"gasPrice"` 606 Value hexutil.Big `json:"value"` 607 Data hexutil.Bytes `json:"data"` 608 } 609 610 func (s *PublicBlockChainAPI) doCall(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber, vmCfg vm.Config, timeout time.Duration) ([]byte, uint64, bool, error) { 611 defer func(start time.Time) { log.Debug("Executing EVM call finished", "runtime", time.Since(start)) }(time.Now()) 612 613 state, header, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 614 if state == nil || err != nil { 615 return nil, 0, false, err 616 } 617 //设置发件人地址,如果未指定,则使用默认值 618 addr := args.From 619 if addr == (common.Address{}) { 620 if wallets := s.b.AccountManager().Wallets(); len(wallets) > 0 { 621 if accounts := wallets[0].Accounts(); len(accounts) > 0 { 622 addr = accounts[0].Address 623 } 624 } 625 } 626 //如果未设置,则设置默认的天然气和天然气价格 627 gas, gasPrice := uint64(args.Gas), args.GasPrice.ToInt() 628 if gas == 0 { 629 gas = math.MaxUint64 / 2 630 } 631 if gasPrice.Sign() == 0 { 632 gasPrice = new(big.Int).SetUint64(defaultGasPrice) 633 } 634 635 //创建新的呼叫消息 636 msg := types.NewMessage(addr, args.To, 0, args.Value.ToInt(), gas, gasPrice, args.Data, false) 637 638 //设置上下文,以便取消调用 639 //或者,对于未计量的气体,设置一个超时上下文。 640 var cancel context.CancelFunc 641 if timeout > 0 { 642 ctx, cancel = context.WithTimeout(ctx, timeout) 643 } else { 644 ctx, cancel = context.WithCancel(ctx) 645 } 646 //确保在调用完成时取消上下文 647 //这可以确保清理资源。 648 defer cancel() 649 650 //获取EVM的新实例。 651 evm, vmError, err := s.b.GetEVM(ctx, msg, state, header, vmCfg) 652 if err != nil { 653 return nil, 0, false, err 654 } 655 //Wait for the context to be done and cancel the evm. 即使 656 //EVM已完成,可以取消(重复) 657 go func() { 658 <-ctx.Done() 659 evm.Cancel() 660 }() 661 662 //设置燃气池(也适用于未计量的请求) 663 //并应用消息。 664 gp := new(core.GasPool).AddGas(math.MaxUint64) 665 res, gas, failed, err := core.ApplyMessage(evm, msg, gp) 666 if err := vmError(); err != nil { 667 return nil, 0, false, err 668 } 669 return res, gas, failed, err 670 } 671 672 //调用对给定块号的状态执行给定事务。 673 //它不会在状态/区块链中进行更改,并且对执行和检索值很有用。 674 func (s *PublicBlockChainAPI) Call(ctx context.Context, args CallArgs, blockNr rpc.BlockNumber) (hexutil.Bytes, error) { 675 result, _, _, err := s.doCall(ctx, args, blockNr, vm.Config{}, 5*time.Second) 676 return (hexutil.Bytes)(result), err 677 } 678 679 //EstimateGas返回执行 680 //针对当前挂起块的给定事务。 681 func (s *PublicBlockChainAPI) EstimateGas(ctx context.Context, args CallArgs) (hexutil.Uint64, error) { 682 //二元搜索气体需求,因为它可能高于使用量 683 var ( 684 lo uint64 = params.TxGas - 1 685 hi uint64 686 cap uint64 687 ) 688 if uint64(args.Gas) >= params.TxGas { 689 hi = uint64(args.Gas) 690 } else { 691 //检索当前挂起的块作为气体天花板 692 block, err := s.b.BlockByNumber(ctx, rpc.PendingBlockNumber) 693 if err != nil { 694 return 0, err 695 } 696 hi = block.GasLimit() 697 } 698 cap = hi 699 700 //创建一个助手以检查气体限额是否导致可执行事务 701 executable := func(gas uint64) bool { 702 args.Gas = hexutil.Uint64(gas) 703 704 _, _, failed, err := s.doCall(ctx, args, rpc.PendingBlockNumber, vm.Config{}, 0) 705 if err != nil || failed { 706 return false 707 } 708 return true 709 } 710 //执行二进制搜索并按可执行的气体限值接通。 711 for lo+1 < hi { 712 mid := (hi + lo) / 2 713 if !executable(mid) { 714 lo = mid 715 } else { 716 hi = mid 717 } 718 } 719 //如果交易仍以最高限额失败,则将其视为无效拒绝交易 720 if hi == cap { 721 if !executable(hi) { 722 return 0, fmt.Errorf("gas required exceeds allowance or always failing transaction") 723 } 724 } 725 return hexutil.Uint64(hi), nil 726 } 727 728 //ExecutionResult将EVM发出的所有结构化日志分组 729 //在调试模式和事务中重播事务时 730 //执行状态、使用的气体量和返回值 731 type ExecutionResult struct { 732 Gas uint64 `json:"gas"` 733 Failed bool `json:"failed"` 734 ReturnValue string `json:"returnValue"` 735 StructLogs []StructLogRes `json:"structLogs"` 736 } 737 738 //structlogres存储EVM在重播时发出的结构化日志 739 //调试模式下的事务处理 740 type StructLogRes struct { 741 Pc uint64 `json:"pc"` 742 Op string `json:"op"` 743 Gas uint64 `json:"gas"` 744 GasCost uint64 `json:"gasCost"` 745 Depth int `json:"depth"` 746 Error error `json:"error,omitempty"` 747 Stack *[]string `json:"stack,omitempty"` 748 Memory *[]string `json:"memory,omitempty"` 749 Storage *map[string]string `json:"storage,omitempty"` 750 } 751 752 //FORMATLOGS FORMATS EVM为JSON输出返回结构化日志 753 func FormatLogs(logs []vm.StructLog) []StructLogRes { 754 formatted := make([]StructLogRes, len(logs)) 755 for index, trace := range logs { 756 formatted[index] = StructLogRes{ 757 Pc: trace.Pc, 758 Op: trace.Op.String(), 759 Gas: trace.Gas, 760 GasCost: trace.GasCost, 761 Depth: trace.Depth, 762 Error: trace.Err, 763 } 764 if trace.Stack != nil { 765 stack := make([]string, len(trace.Stack)) 766 for i, stackValue := range trace.Stack { 767 stack[i] = fmt.Sprintf("%x", math.PaddedBigBytes(stackValue, 32)) 768 } 769 formatted[index].Stack = &stack 770 } 771 if trace.Memory != nil { 772 memory := make([]string, 0, (len(trace.Memory)+31)/32) 773 for i := 0; i+32 <= len(trace.Memory); i += 32 { 774 memory = append(memory, fmt.Sprintf("%x", trace.Memory[i:i+32])) 775 } 776 formatted[index].Memory = &memory 777 } 778 if trace.Storage != nil { 779 storage := make(map[string]string) 780 for i, storageValue := range trace.Storage { 781 storage[fmt.Sprintf("%x", i)] = fmt.Sprintf("%x", storageValue) 782 } 783 formatted[index].Storage = &storage 784 } 785 } 786 return formatted 787 } 788 789 //rpcmarshalblock将给定的块转换为依赖于fulltx的rpc输出。如果incltx为真,则事务为 790 //返回。当fulltx为true时,返回的块包含完整的事务详细信息,否则它将只包含 791 //事务哈希。 792 func RPCMarshalBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 793 head := b.Header() //复制头一次 794 fields := map[string]interface{}{ 795 "number": (*hexutil.Big)(head.Number), 796 "hash": b.Hash(), 797 "parentHash": head.ParentHash, 798 "nonce": head.Nonce, 799 "mixHash": head.MixDigest, 800 "sha3Uncles": head.UncleHash, 801 "logsBloom": head.Bloom, 802 "stateRoot": head.Root, 803 "miner": head.Coinbase, 804 "difficulty": (*hexutil.Big)(head.Difficulty), 805 "extraData": hexutil.Bytes(head.Extra), 806 "size": hexutil.Uint64(b.Size()), 807 "gasLimit": hexutil.Uint64(head.GasLimit), 808 "gasUsed": hexutil.Uint64(head.GasUsed), 809 "timestamp": (*hexutil.Big)(head.Time), 810 "transactionsRoot": head.TxHash, 811 "receiptsRoot": head.ReceiptHash, 812 } 813 814 if inclTx { 815 formatTx := func(tx *types.Transaction) (interface{}, error) { 816 return tx.Hash(), nil 817 } 818 if fullTx { 819 formatTx = func(tx *types.Transaction) (interface{}, error) { 820 return newRPCTransactionFromBlockHash(b, tx.Hash()), nil 821 } 822 } 823 txs := b.Transactions() 824 transactions := make([]interface{}, len(txs)) 825 var err error 826 for i, tx := range txs { 827 if transactions[i], err = formatTx(tx); err != nil { 828 return nil, err 829 } 830 } 831 fields["transactions"] = transactions 832 } 833 834 uncles := b.Uncles() 835 uncleHashes := make([]common.Hash, len(uncles)) 836 for i, uncle := range uncles { 837 uncleHashes[i] = uncle.Hash() 838 } 839 fields["uncles"] = uncleHashes 840 841 return fields, nil 842 } 843 844 //rpcoutputblock使用通用的输出填充符,然后添加总难度字段,这需要 845 //一个“publicBlockChainAPI”。 846 func (s *PublicBlockChainAPI) rpcOutputBlock(b *types.Block, inclTx bool, fullTx bool) (map[string]interface{}, error) { 847 fields, err := RPCMarshalBlock(b, inclTx, fullTx) 848 if err != nil { 849 return nil, err 850 } 851 fields["totalDifficulty"] = (*hexutil.Big)(s.b.GetTd(b.Hash())) 852 return fields, err 853 } 854 855 //rpc transaction表示将序列化为事务的rpc表示形式的事务 856 type RPCTransaction struct { 857 BlockHash common.Hash `json:"blockHash"` 858 BlockNumber *hexutil.Big `json:"blockNumber"` 859 From common.Address `json:"from"` 860 Gas hexutil.Uint64 `json:"gas"` 861 GasPrice *hexutil.Big `json:"gasPrice"` 862 Hash common.Hash `json:"hash"` 863 Input hexutil.Bytes `json:"input"` 864 Nonce hexutil.Uint64 `json:"nonce"` 865 To *common.Address `json:"to"` 866 TransactionIndex hexutil.Uint `json:"transactionIndex"` 867 Value *hexutil.Big `json:"value"` 868 V *hexutil.Big `json:"v"` 869 R *hexutil.Big `json:"r"` 870 S *hexutil.Big `json:"s"` 871 } 872 873 //NewRpcTransaction返回将序列化到RPC的事务 874 //表示法,使用给定的位置元数据集(如果可用)。 875 func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber uint64, index uint64) *RPCTransaction { 876 var signer types.Signer = types.FrontierSigner{} 877 if tx.Protected() { 878 signer = types.NewEIP155Signer(tx.ChainId()) 879 } 880 from, _ := types.Sender(signer, tx) 881 v, r, s := tx.RawSignatureValues() 882 883 result := &RPCTransaction{ 884 From: from, 885 Gas: hexutil.Uint64(tx.Gas()), 886 GasPrice: (*hexutil.Big)(tx.GasPrice()), 887 Hash: tx.Hash(), 888 Input: hexutil.Bytes(tx.Data()), 889 Nonce: hexutil.Uint64(tx.Nonce()), 890 To: tx.To(), 891 Value: (*hexutil.Big)(tx.Value()), 892 V: (*hexutil.Big)(v), 893 R: (*hexutil.Big)(r), 894 S: (*hexutil.Big)(s), 895 } 896 if blockHash != (common.Hash{}) { 897 result.BlockHash = blockHash 898 result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber)) 899 result.TransactionIndex = hexutil.Uint(index) 900 } 901 return result 902 } 903 904 //NewRpcPendingTransaction返回一个挂起的事务,该事务将序列化为RPC表示形式 905 func newRPCPendingTransaction(tx *types.Transaction) *RPCTransaction { 906 return newRPCTransaction(tx, common.Hash{}, 0, 0) 907 } 908 909 //newRpcTransactionFromBlockIndex返回将序列化到RPC表示形式的事务。 910 func newRPCTransactionFromBlockIndex(b *types.Block, index uint64) *RPCTransaction { 911 txs := b.Transactions() 912 if index >= uint64(len(txs)) { 913 return nil 914 } 915 return newRPCTransaction(txs[index], b.Hash(), b.NumberU64(), index) 916 } 917 918 //newrpcrawTransactionFromBlockIndex返回给定块和事务索引的事务的字节。 919 func newRPCRawTransactionFromBlockIndex(b *types.Block, index uint64) hexutil.Bytes { 920 txs := b.Transactions() 921 if index >= uint64(len(txs)) { 922 return nil 923 } 924 blob, _ := rlp.EncodeToBytes(txs[index]) 925 return blob 926 } 927 928 //newRpcTransactionFromBlockHash返回将序列化到RPC表示形式的事务。 929 func newRPCTransactionFromBlockHash(b *types.Block, hash common.Hash) *RPCTransaction { 930 for idx, tx := range b.Transactions() { 931 if tx.Hash() == hash { 932 return newRPCTransactionFromBlockIndex(b, uint64(idx)) 933 } 934 } 935 return nil 936 } 937 938 //PublicTransactionPoolapi公开RPC接口的方法 939 type PublicTransactionPoolAPI struct { 940 b Backend 941 nonceLock *AddrLocker 942 } 943 944 //NewPublicTransactionPoolapi使用特定于事务池的方法创建新的RPC服务。 945 func NewPublicTransactionPoolAPI(b Backend, nonceLock *AddrLocker) *PublicTransactionPoolAPI { 946 return &PublicTransactionPoolAPI{b, nonceLock} 947 } 948 949 //GetBlockTransactionCountByNumber返回具有给定块号的块中的事务数。 950 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByNumber(ctx context.Context, blockNr rpc.BlockNumber) *hexutil.Uint { 951 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 952 n := hexutil.Uint(len(block.Transactions())) 953 return &n 954 } 955 return nil 956 } 957 958 //GetBlockTransactionCountByHash返回具有给定哈希的块中的事务数。 959 func (s *PublicTransactionPoolAPI) GetBlockTransactionCountByHash(ctx context.Context, blockHash common.Hash) *hexutil.Uint { 960 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 961 n := hexutil.Uint(len(block.Transactions())) 962 return &n 963 } 964 return nil 965 } 966 967 //GetTransactionByBlockNumberAndIndex返回给定块号和索引的事务。 968 func (s *PublicTransactionPoolAPI) GetTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) *RPCTransaction { 969 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 970 return newRPCTransactionFromBlockIndex(block, uint64(index)) 971 } 972 return nil 973 } 974 975 //GetTransactionByBlockHashAndIndex返回给定块哈希和索引的事务。 976 func (s *PublicTransactionPoolAPI) GetTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) *RPCTransaction { 977 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 978 return newRPCTransactionFromBlockIndex(block, uint64(index)) 979 } 980 return nil 981 } 982 983 //GetRawTransactionByBlockNumberAndIndex返回给定块号和索引的事务字节。 984 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockNumberAndIndex(ctx context.Context, blockNr rpc.BlockNumber, index hexutil.Uint) hexutil.Bytes { 985 if block, _ := s.b.BlockByNumber(ctx, blockNr); block != nil { 986 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 987 } 988 return nil 989 } 990 991 //GetRawTransactionByBlockHashAndIndex返回给定块哈希和索引的事务字节。 992 func (s *PublicTransactionPoolAPI) GetRawTransactionByBlockHashAndIndex(ctx context.Context, blockHash common.Hash, index hexutil.Uint) hexutil.Bytes { 993 if block, _ := s.b.GetBlock(ctx, blockHash); block != nil { 994 return newRPCRawTransactionFromBlockIndex(block, uint64(index)) 995 } 996 return nil 997 } 998 999 //GetTransactionCount返回给定地址为给定块号发送的事务数。 1000 func (s *PublicTransactionPoolAPI) GetTransactionCount(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (*hexutil.Uint64, error) { 1001 state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr) 1002 if state == nil || err != nil { 1003 return nil, err 1004 } 1005 nonce := state.GetNonce(address) 1006 return (*hexutil.Uint64)(&nonce), state.Error() 1007 } 1008 1009 //GetTransactionByHash返回给定哈希的事务 1010 func (s *PublicTransactionPoolAPI) GetTransactionByHash(ctx context.Context, hash common.Hash) *RPCTransaction { 1011 //尝试返回已完成的事务 1012 if tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash); tx != nil { 1013 return newRPCTransaction(tx, blockHash, blockNumber, index) 1014 } 1015 //没有完成的事务,请尝试从池中检索它 1016 if tx := s.b.GetPoolTransaction(hash); tx != nil { 1017 return newRPCPendingTransaction(tx) 1018 } 1019 //事务未知,因此返回 1020 return nil 1021 } 1022 1023 //GetRawTransactionByHash返回给定哈希的事务字节。 1024 func (s *PublicTransactionPoolAPI) GetRawTransactionByHash(ctx context.Context, hash common.Hash) (hexutil.Bytes, error) { 1025 var tx *types.Transaction 1026 1027 //检索已完成的事务,或以其他方式合并 1028 if tx, _, _, _ = rawdb.ReadTransaction(s.b.ChainDb(), hash); tx == nil { 1029 if tx = s.b.GetPoolTransaction(hash); tx == nil { 1030 //找不到事务,中止 1031 return nil, nil 1032 } 1033 } 1034 //序列化到rlp并返回 1035 return rlp.EncodeToBytes(tx) 1036 } 1037 1038 //GetTransactionReceipt返回给定事务哈希的事务回执。 1039 func (s *PublicTransactionPoolAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { 1040 tx, blockHash, blockNumber, index := rawdb.ReadTransaction(s.b.ChainDb(), hash) 1041 if tx == nil { 1042 return nil, nil 1043 } 1044 receipts, err := s.b.GetReceipts(ctx, blockHash) 1045 if err != nil { 1046 return nil, err 1047 } 1048 if len(receipts) <= int(index) { 1049 return nil, nil 1050 } 1051 receipt := receipts[index] 1052 1053 var signer types.Signer = types.FrontierSigner{} 1054 if tx.Protected() { 1055 signer = types.NewEIP155Signer(tx.ChainId()) 1056 } 1057 from, _ := types.Sender(signer, tx) 1058 1059 fields := map[string]interface{}{ 1060 "blockHash": blockHash, 1061 "blockNumber": hexutil.Uint64(blockNumber), 1062 "transactionHash": hash, 1063 "transactionIndex": hexutil.Uint64(index), 1064 "from": from, 1065 "to": tx.To(), 1066 "gasUsed": hexutil.Uint64(receipt.GasUsed), 1067 "cumulativeGasUsed": hexutil.Uint64(receipt.CumulativeGasUsed), 1068 "contractAddress": nil, 1069 "logs": receipt.Logs, 1070 "logsBloom": receipt.Bloom, 1071 } 1072 1073 //分配收据状态或过账状态。 1074 if len(receipt.PostState) > 0 { 1075 fields["root"] = hexutil.Bytes(receipt.PostState) 1076 } else { 1077 fields["status"] = hexutil.Uint(receipt.Status) 1078 } 1079 if receipt.Logs == nil { 1080 fields["logs"] = [][]*types.Log{} 1081 } 1082 //如果contractAddress为20 0x0字节,则假定它不是合同创建 1083 if receipt.ContractAddress != (common.Address{}) { 1084 fields["contractAddress"] = receipt.ContractAddress 1085 } 1086 return fields, nil 1087 } 1088 1089 //sign是一个助手函数,它使用给定地址的私钥对事务进行签名。 1090 func (s *PublicTransactionPoolAPI) sign(addr common.Address, tx *types.Transaction) (*types.Transaction, error) { 1091 //查找包含请求签名者的钱包 1092 account := accounts.Account{Address: addr} 1093 1094 wallet, err := s.b.AccountManager().Find(account) 1095 if err != nil { 1096 return nil, err 1097 } 1098 //请求钱包签署交易 1099 var chainID *big.Int 1100 if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { 1101 chainID = config.ChainID 1102 } 1103 return wallet.SignTx(account, tx, chainID) 1104 } 1105 1106 //sendtxargs表示向事务池中sumbit新事务的参数。 1107 type SendTxArgs struct { 1108 From common.Address `json:"from"` 1109 To *common.Address `json:"to"` 1110 Gas *hexutil.Uint64 `json:"gas"` 1111 GasPrice *hexutil.Big `json:"gasPrice"` 1112 Value *hexutil.Big `json:"value"` 1113 Nonce *hexutil.Uint64 `json:"nonce"` 1114 //出于向后兼容性的原因,我们接受“数据”和“输入”。“输入”是 1115 //更新的名称,应为客户首选。 1116 Data *hexutil.Bytes `json:"data"` 1117 Input *hexutil.Bytes `json:"input"` 1118 Type types.TxType `json:"type"` 1119 } 1120 1121 //setdefaults是一个帮助函数,它为未指定的tx字段填充默认值。 1122 func (args *SendTxArgs) setDefaults(ctx context.Context, b Backend) error { 1123 if args.Gas == nil { 1124 args.Gas = new(hexutil.Uint64) 1125 *(*uint64)(args.Gas) = 90000 1126 } 1127 if args.GasPrice == nil { 1128 price, err := b.SuggestPrice(ctx) 1129 if err != nil { 1130 return err 1131 } 1132 args.GasPrice = (*hexutil.Big)(price) 1133 } 1134 if args.Value == nil { 1135 args.Value = new(hexutil.Big) 1136 } 1137 if args.Nonce == nil { 1138 nonce, err := b.GetPoolNonce(ctx, args.From) 1139 if err != nil { 1140 return err 1141 } 1142 args.Nonce = (*hexutil.Uint64)(&nonce) 1143 } 1144 if args.Data != nil && args.Input != nil && !bytes.Equal(*args.Data, *args.Input) { 1145 return errors.New(`Both "data" and "input" are set and not equal. Please use "input" to pass transaction call data.`) 1146 } 1147 if args.To == nil { 1148 //合同创建 1149 var input []byte 1150 if args.Data != nil { 1151 input = *args.Data 1152 } else if args.Input != nil { 1153 input = *args.Input 1154 } 1155 if len(input) == 0 { 1156 return errors.New(`contract creation without any data provided`) 1157 } 1158 } 1159 return nil 1160 } 1161 /* 1162 func(args*sendtxargs)toTransaction()*types.transaction_ 1163 var输入[]字节 1164 如果是ARG.数据!= nIL{ 1165 输入=*args.data 1166 否则,如果参数输入!= nIL{ 1167 输入=*args.input 1168 } 1169 如果args.to==nil 1170 返回类型.newContractCreation(uint64(*args.nonce),(*big.int)(args.value),uint64(*args.gas),(*big.int)(args.gasprice),input) 1171 } 1172 返回类型.newTransaction(uint64(*args.nonce),*args.to,(*big.int)(args.value),uint64(*args.gas),(*big.int)(args.gasprice),input) 1173 */ 1174 1175 func (args *SendTxArgs) toTransaction() *types.Transaction { 1176 var input []byte 1177 if args.Data != nil { 1178 input = *args.Data 1179 } else if args.Input != nil { 1180 input = *args.Input 1181 } 1182 if args.Type == types.Binary && args.To == nil { 1183 return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), *args.Data) 1184 } 1185 if args.To == nil { 1186 return types.NewContractCreation(uint64(*args.Nonce), (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) 1187 } 1188 return types.NewTransaction(0, uint64(*args.Nonce), *args.To, (*big.Int)(args.Value), uint64(*args.Gas), (*big.Int)(args.GasPrice), input) 1189 } 1190 1191 //SubmitTransaction是一个助手函数,它将Tx提交到TxPool并记录消息。 1192 func submitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (common.Hash, error) { 1193 if err := b.SendTx(ctx, tx); err != nil { 1194 return common.Hash{}, err 1195 } 1196 if tx.To() == nil { 1197 signer := types.MakeSigner(b.ChainConfig(), b.CurrentBlock().Number()) 1198 from, err := types.Sender(signer, tx) 1199 if err != nil { 1200 return common.Hash{}, err 1201 } 1202 addr := crypto.CreateAddress(from, tx.Nonce()) 1203 log.Info("Submitted contract creation", "fullhash", tx.Hash().Hex(), "contract", addr.Hex()) 1204 } else { 1205 log.Info("Submitted transaction", "fullhash", tx.Hash().Hex(), "recipient", tx.To()) 1206 } 1207 return tx.Hash(), nil 1208 } 1209 1210 //sendTransaction为给定参数创建一个事务,对其签名并将其提交给 1211 //事务池。 1212 func (s *PublicTransactionPoolAPI) SendTransaction(ctx context.Context, args SendTxArgs) (common.Hash, error) { 1213 1214 //查找包含请求签名者的钱包 1215 account := accounts.Account{Address: args.From} 1216 1217 wallet, err := s.b.AccountManager().Find(account) 1218 if err != nil { 1219 return common.Hash{}, err 1220 } 1221 1222 if args.Nonce == nil { 1223 //在签名周围保持地址的互斥体,以防止同时分配 1224 //对多个帐户使用同一个nonce。 1225 s.nonceLock.LockAddr(args.From) 1226 defer s.nonceLock.UnlockAddr(args.From) 1227 } 1228 1229 //设置一些健全的默认值并在失败时终止 1230 if err := args.setDefaults(ctx, s.b); err != nil { 1231 return common.Hash{}, err 1232 } 1233 //整理交易并用钱包签名 1234 tx := args.toTransaction() 1235 1236 var chainID *big.Int 1237 if config := s.b.ChainConfig(); config.IsEIP155(s.b.CurrentBlock().Number()) { 1238 chainID = config.ChainID 1239 } 1240 signed, err := wallet.SignTx(account, tx, chainID) 1241 if err != nil { 1242 return common.Hash{}, err 1243 } 1244 return submitTransaction(ctx, s.b, signed) 1245 } 1246 1247 //sendrawtransaction将把签名的事务添加到事务池中。 1248 //发送方负责签署事务并使用正确的nonce。 1249 func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encodedTx hexutil.Bytes) (common.Hash, error) { 1250 tx := new(types.Transaction) 1251 if err := rlp.DecodeBytes(encodedTx, tx); err != nil { 1252 return common.Hash{}, err 1253 } 1254 return submitTransaction(ctx, s.b, tx) 1255 } 1256 1257 //sign为以下项计算ECDSA签名: 1258 //keccack256(“\x19ethereum签名消息:\n”+len(消息)+消息)。 1259 // 1260 //注:生成的签名符合secp256k1曲线r、s和v值, 1261 //由于遗产原因,V值将为27或28。 1262 // 1263 //必须解锁与addr关联的帐户。 1264 // 1265 //https://github.com/ethereum/wiki/wiki/json-rpc eth_符号 1266 func (s *PublicTransactionPoolAPI) Sign(addr common.Address, data hexutil.Bytes) (hexutil.Bytes, error) { 1267 //查找包含请求签名者的钱包 1268 account := accounts.Account{Address: addr} 1269 1270 wallet, err := s.b.AccountManager().Find(account) 1271 if err != nil { 1272 return nil, err 1273 } 1274 //用钱包在请求的哈希表上签名 1275 signature, err := wallet.SignHash(account, signHash(data)) 1276 if err == nil { 1277 signature[64] += 27 //根据黄纸将V从0/1转换为27/28 1278 } 1279 return signature, err 1280 } 1281 1282 //SignTransactionResult表示RLP编码的签名事务。 1283 type SignTransactionResult struct { 1284 Raw hexutil.Bytes `json:"raw"` 1285 Tx *types.Transaction `json:"tx"` 1286 } 1287 1288 //SignTransaction将使用From帐户对给定的事务进行签名。 1289 //节点需要具有与 1290 //从地址发出,需要解锁。 1291 func (s *PublicTransactionPoolAPI) SignTransaction(ctx context.Context, args SendTxArgs) (*SignTransactionResult, error) { 1292 if args.Gas == nil { 1293 return nil, fmt.Errorf("gas not specified") 1294 } 1295 if args.GasPrice == nil { 1296 return nil, fmt.Errorf("gasPrice not specified") 1297 } 1298 if args.Nonce == nil { 1299 return nil, fmt.Errorf("nonce not specified") 1300 } 1301 if err := args.setDefaults(ctx, s.b); err != nil { 1302 return nil, err 1303 } 1304 tx, err := s.sign(args.From, args.toTransaction()) 1305 if err != nil { 1306 return nil, err 1307 } 1308 data, err := rlp.EncodeToBytes(tx) 1309 if err != nil { 1310 return nil, err 1311 } 1312 return &SignTransactionResult{data, tx}, nil 1313 } 1314 1315 //PendingtTransactions返回事务池中的事务 1316 //并且有一个发件人地址,该地址是此节点管理的帐户之一。 1317 func (s *PublicTransactionPoolAPI) PendingTransactions() ([]*RPCTransaction, error) { 1318 pending, err := s.b.GetPoolTransactions() 1319 if err != nil { 1320 return nil, err 1321 } 1322 accounts := make(map[common.Address]struct{}) 1323 for _, wallet := range s.b.AccountManager().Wallets() { 1324 for _, account := range wallet.Accounts() { 1325 accounts[account.Address] = struct{}{} 1326 } 1327 } 1328 transactions := make([]*RPCTransaction, 0, len(pending)) 1329 for _, tx := range pending { 1330 var signer types.Signer = types.HomesteadSigner{} 1331 if tx.Protected() { 1332 signer = types.NewEIP155Signer(tx.ChainId()) 1333 } 1334 from, _ := types.Sender(signer, tx) 1335 if _, exists := accounts[from]; exists { 1336 transactions = append(transactions, newRPCPendingTransaction(tx)) 1337 } 1338 } 1339 return transactions, nil 1340 } 1341 1342 //重新发送接受现有交易和新的天然气价格和限额。它将移除 1343 //从池中指定的交易,并重新插入新的天然气价格和限额。 1344 func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, sendArgs SendTxArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { 1345 if sendArgs.Nonce == nil { 1346 return common.Hash{}, fmt.Errorf("missing transaction nonce in transaction spec") 1347 } 1348 if err := sendArgs.setDefaults(ctx, s.b); err != nil { 1349 return common.Hash{}, err 1350 } 1351 matchTx := sendArgs.toTransaction() 1352 pending, err := s.b.GetPoolTransactions() 1353 if err != nil { 1354 return common.Hash{}, err 1355 } 1356 1357 for _, p := range pending { 1358 var signer types.Signer = types.HomesteadSigner{} 1359 if p.Protected() { 1360 signer = types.NewEIP155Signer(p.ChainId()) 1361 } 1362 wantSigHash := signer.Hash(matchTx) 1363 1364 if pFrom, err := types.Sender(signer, p); err == nil && pFrom == sendArgs.From && signer.Hash(p) == wantSigHash { 1365 //比赛。重新签署并发送交易。 1366 if gasPrice != nil && (*big.Int)(gasPrice).Sign() != 0 { 1367 sendArgs.GasPrice = gasPrice 1368 } 1369 if gasLimit != nil && *gasLimit != 0 { 1370 sendArgs.Gas = gasLimit 1371 } 1372 signedTx, err := s.sign(sendArgs.From, sendArgs.toTransaction()) 1373 if err != nil { 1374 return common.Hash{}, err 1375 } 1376 if err = s.b.SendTx(ctx, signedTx); err != nil { 1377 return common.Hash{}, err 1378 } 1379 return signedTx.Hash(), nil 1380 } 1381 } 1382 1383 return common.Hash{}, fmt.Errorf("Transaction %#x not found", matchTx.Hash()) 1384 } 1385 1386 //publicDebugAPI是公开的以太坊API集合 1387 //调试终结点。 1388 type PublicDebugAPI struct { 1389 b Backend 1390 } 1391 1392 //NewPublicDebugGapi为公共调试方法创建新的API定义 1393 //以太坊服务。 1394 func NewPublicDebugAPI(b Backend) *PublicDebugAPI { 1395 return &PublicDebugAPI{b: b} 1396 } 1397 1398 //getblockrlp检索为单个块编码的rlp。 1399 func (api *PublicDebugAPI) GetBlockRlp(ctx context.Context, number uint64) (string, error) { 1400 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1401 if block == nil { 1402 return "", fmt.Errorf("block #%d not found", number) 1403 } 1404 encoded, err := rlp.EncodeToBytes(block) 1405 if err != nil { 1406 return "", err 1407 } 1408 return fmt.Sprintf("%x", encoded), nil 1409 } 1410 1411 //printblock检索一个块并返回其漂亮的打印表单。 1412 func (api *PublicDebugAPI) PrintBlock(ctx context.Context, number uint64) (string, error) { 1413 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1414 if block == nil { 1415 return "", fmt.Errorf("block #%d not found", number) 1416 } 1417 return spew.Sdump(block), nil 1418 } 1419 1420 //seed hash检索块的种子哈希。 1421 func (api *PublicDebugAPI) SeedHash(ctx context.Context, number uint64) (string, error) { 1422 block, _ := api.b.BlockByNumber(ctx, rpc.BlockNumber(number)) 1423 if block == nil { 1424 return "", fmt.Errorf("block #%d not found", number) 1425 } 1426 return fmt.Sprintf("0x%x", ethash.SeedHash(number)), nil 1427 } 1428 1429 //privatedebugapi是在私有服务器上公开的以太坊API的集合。 1430 //调试终结点。 1431 type PrivateDebugAPI struct { 1432 b Backend 1433 } 1434 1435 //new private debug api为专用调试方法创建新的API定义 1436 //以太坊服务。 1437 func NewPrivateDebugAPI(b Backend) *PrivateDebugAPI { 1438 return &PrivateDebugAPI{b: b} 1439 } 1440 1441 //chainedbproperty返回链数据库的leveldb属性。 1442 func (api *PrivateDebugAPI) ChaindbProperty(property string) (string, error) { 1443 ldb, ok := api.b.ChainDb().(interface { 1444 LDB() *leveldb.DB 1445 }) 1446 if !ok { 1447 return "", fmt.Errorf("chaindbProperty does not work for memory databases") 1448 } 1449 if property == "" { 1450 property = "leveldb.stats" 1451 } else if !strings.HasPrefix(property, "leveldb.") { 1452 property = "leveldb." + property 1453 } 1454 return ldb.LDB().GetProperty(property) 1455 } 1456 1457 func (api *PrivateDebugAPI) ChaindbCompact() error { 1458 ldb, ok := api.b.ChainDb().(interface { 1459 LDB() *leveldb.DB 1460 }) 1461 if !ok { 1462 return fmt.Errorf("chaindbCompact does not work for memory databases") 1463 } 1464 for b := byte(0); b < 255; b++ { 1465 log.Info("Compacting chain database", "range", fmt.Sprintf("0x%0.2X-0x%0.2X", b, b+1)) 1466 err := ldb.LDB().CompactRange(util.Range{Start: []byte{b}, Limit: []byte{b + 1}}) 1467 if err != nil { 1468 log.Error("Database compaction failed", "err", err) 1469 return err 1470 } 1471 } 1472 return nil 1473 } 1474 1475 //sethead将区块链的头倒回到上一个块。 1476 func (api *PrivateDebugAPI) SetHead(number hexutil.Uint64) { 1477 api.b.SetHead(uint64(number)) 1478 } 1479 1480 //PublicNetAPI提供与网络相关的RPC方法 1481 type PublicNetAPI struct { 1482 net *p2p.Server 1483 networkVersion uint64 1484 } 1485 1486 //NewPublicNetAPI创建新的NET API实例。 1487 func NewPublicNetAPI(net *p2p.Server, networkVersion uint64) *PublicNetAPI { 1488 return &PublicNetAPI{net, networkVersion} 1489 } 1490 1491 //侦听返回节点是否正在侦听网络连接的指示。 1492 func (s *PublicNetAPI) Listening() bool { 1493 return true //总是倾听 1494 } 1495 1496 //PeerCount返回连接的对等数 1497 func (s *PublicNetAPI) PeerCount() hexutil.Uint { 1498 return hexutil.Uint(s.net.PeerCount()) 1499 } 1500 1501 //version返回当前的以太坊协议版本。 1502 func (s *PublicNetAPI) Version() string { 1503 return fmt.Sprintf("%d", s.networkVersion) 1504 } 1505