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