typetxdatastruct{AccountNonceuint64`json:"nonce" gencodec:"required"`Price*big.Int`json:"gasPrice" gencodec:"required"`GasLimituint64`json:"gas" gencodec:"required"`Recipient*common.Address`json:"to" rlp:"nil"`// nil means contract creationAmount*big.Int`json:"value" gencodec:"required"`Payload[]byte`json:"input" gencodec:"required"`// Signature valuesV*big.Int`json:"v" gencodec:"required"`R*big.Int`json:"r" gencodec:"required"`S*big.Int`json:"s" gencodec:"required"`// This is only used when marshaling to JSON.Hash*common.Hash`json:"hash" rlp:"-"`}
// Creates an ethereum address given the bytes and the noncefuncCreateAddress(bcommon.Address,nonceuint64)common.Address{data,_:=rlp.EncodeToBytes([]interface{}{b,nonce})returncommon.BytesToAddress(Keccak256(data)[12:])}
是否重复交易
通过检查交易池里是否存在该交易hash判断是否是重复交易
1234
hash:=tx.Hash()ifpool.all[hash]!=nil{log.Trace("Discarding already known transaction","hash",hash)returnfalse,fmt.Errorf("known transaction: %x",
// Discard finds a number of most underpriced transactions, removes them from the// priced list and returns them for further removal from the entire pool.func(l*txPricedList)Discard(countint,local*accountSet)types.Transactions{drop:=make(types.Transactions,0,count)// Remote underpriced transactions to dropsave:=make(types.Transactions,0,64)// Local underpriced transactions to keepforlen(*l.items)>0&&count>0{// Discard stale transactions if found during cleanuptx:=heap.Pop(l.items).(*types.Transaction)if_,ok:=(*l.all)[tx.Hash()];!ok{l.stales--continue}// Non stale transaction found, discard unless localiflocal.containsTx(tx){save=append(save,tx)}else{drop=append(drop,tx)count--}}for_,tx:=rangesave{heap.Push(l.items,tx)}returndrop}
unc(st*StateTransition)TransitionDb()(ret[]byte,usedGasuint64,failedbool,errerror){...// 1. 该函数根据交易数据检查是否超出基本gas限制,会抛出我们常见的vm.ErrOutOfGas(out of gas),注意此处抛出的错误会使得交易完全回滚gas,err:=IntrinsicGas(st.data,contractCreation,homestead)iferr=st.useGas(gas);err!=nil{returnnil,0,false,err}var(evm=st.evmvmerrerror)// 2.这里如果返回错误(vmerr!=nil)则说明交易执行失败ifcontractCreation{ret,_,st.gas,vmerr=evm.Create(sender,st.data,st.gas,st.value)}else{// Increment the nonce for the next transactionst.state.SetNonce(sender.Address(),st.state.GetNonce(sender.Address())+1)ret,st.gas,vmerr=evm.Call(sender,st.to().Address(),st.data,st.gas,st.value)}ifvmerr!=nil{// 余额不足("insufficient balance for transfer")错误也会导致交易完全回滚ifvmerr==vm.ErrInsufficientBalance{returnnil,0,false,vmerr}}// 退回剩余的gasst.refundGas()st.state.AddBalance(st.evm.Coinbase,new(big.Int).Mul(new(big.Int).SetUint64(st.gasUsed()),st.gasPrice))// 3.vmerr不为空将导致交易失败,但仍能正确打包returnret,st.gasUsed(),vmerr!=nil,err}