上篇文章《以太坊交易簽名過程原始碼解析》從原始碼角度分析了乙個合約呼叫的的簽名過程,簽名後的交易傳送到以太坊節點後,節點需要從簽名交易中還原出公鑰(從公鑰中單向計算出賬號位址),進而將交易放入交易池中。
本文從 go-ethereum 原始碼的出發,看看如何從簽名交易中還原出公鑰。
我們使用上文中最後得到的簽名交易串來進行解析,這裡我寫的解析**如下所示。
// rlp解碼
tx := new(types.transaction)
if err := rlp.decodebytes(encodedtx, tx); err != nil
// chainid為1的eip155簽名器
signer := types.neweip155signer(big.newint(1))
// 使用簽名器從已簽名的交易中還原賬戶公鑰
from, err := types.sender(signer, tx)
if err != nil
fmt.println("from: ", from.hex())
jsontx, _ := tx.marshaljson()
fmt.println("tx: ", string(jsontx))
}其中:types.sender
方法中核心呼叫了 eip155 簽名器的sender
方法,其原始碼如下。
// go-ethereum/core/types/transaction_signing.go
func (s eip155signer) sender(tx *transaction) (common.address, error) .sender(tx)
} if tx.chainid().cmp(s.chainid) != 0 , errinvalidchainid
} //③
v := new(big.int).sub(tx.data.v, s.chainidmul)
v.sub(v, big8)
return recoverplain(s.hash(tx), tx.data.r, tx.data.s, v, true)
}
sender
方法中:
recoverplain 原始碼如下所示。
其中 recoverplain 方法的引數分別為:// go-ethereum/core/types/transaction_signing.go
func recoverplain(sighash common.hash, r, s, vb *big.int, homestead bool) (common.address, error) , errinvalidsig
} v := byte(vb.uint64() - 27)
if !crypto.validatesignaturevalues(v, r, s, homestead) , errinvalidsig
} // encode the signature in uncompressed format
r, s := r.bytes(), s.bytes()
sig := make(byte, crypto.signaturelength)
copy(sig[32-len(r):32], r)
copy(sig[64-len(s):64], s)
sig[64] = v //①
fmt.println("sig: ", common.bytes2hex(sig))
// recover the public key from the signature
pub, err := crypto.ecrecover(sighash[:], sig) //②
if err != nil , err
} if len(pub) == 0 || pub[0] != 4 , errors.new("invalid public key")
} fmt.println("pub: ", common.bytes2hex(pub))
var addr common.address
copy(addr[:], crypto.keccak256(pub[1:])[12:])//③
return addr, nil
}
在 recoverplain 方法中:
至此,我們已經從簽名中還原出了賬號位址(公鑰)。如果需要校驗簽名是否正確,可以通過呼叫 secp256k1 包中的verifysignature
方法,傳入公鑰、交易 hash 和簽名,通過比對 r 值是否一致進行驗證。
登鏈社群 - 區塊鏈技術愛好者的家園
以太坊交易簽名
以太坊的transcation結構如下 以下為交易本身資料資訊 let accountnonce uint64 let price bigint let gaslimit bigint let recipient address let amount biguint var payload data...
以太坊原始碼 交易(一)
交易是區塊鏈中最基本也是最核心的乙個概念,在以太坊中,交易更是重中之重,因為以太坊是乙個智慧型合約平台,以太坊上的應用都是通過智慧型合約與區塊鏈進行互動,而智慧型合約的執行是由交易觸發的,沒有交易,智慧型合約就是一段死的 可以說在以太坊中,一切都源於交易。下面就來看看在以太坊中交易是什麼樣的,交易裡...
以太坊原始碼分析 交易的執行
以太坊是乙個執行智慧型合約的平台,被稱作可程式設計的區塊鏈,允許使用者將編寫的智慧型合約部署在區塊鏈上執行。而執行合約的主體便是以太坊虛擬機器 evm 區塊 交易 合約 區塊鏈由區塊 block 組成,而區塊中打包一定數量的交易 transaction 交易可能是乙個單純的轉賬操作,也可能是呼叫乙個...