diff --git a/core/types/l2trace.go b/core/types/l2trace.go index e794d21804ee..bc80f4d43a44 100644 --- a/core/types/l2trace.go +++ b/core/types/l2trace.go @@ -107,6 +107,9 @@ type ExtraData struct { // Indicate the call succeeds or not for CALL/CREATE op CallFailed bool `json:"callFailed,omitempty"` // CALL | CALLCODE | DELEGATECALL | STATICCALL: [tx.to address’s code, stack.nth_last(1) address’s code] + // CREATE | CREATE2: [created contract’s code] + // CODESIZE | CODECOPY: [contract’s code] + // EXTCODESIZE | EXTCODECOPY: [stack.nth_last(0) address’s code] CodeList []string `json:"codeList,omitempty"` // SSTORE | SLOAD: [storageProof] // SELFDESTRUCT: [contract address’s account, stack.nth_last(0) address’s account] diff --git a/core/vm/logger.go b/core/vm/logger.go index b73449a8ec6b..93b11f06baa3 100644 --- a/core/vm/logger.go +++ b/core/vm/logger.go @@ -349,6 +349,8 @@ func (l *StructLogger) CaptureExit(output []byte, gasUsed uint64, err error) { lastAccData := theLog.ExtraData.StateList[dataLen-1] wrappedStatus := getWrappedAccountForAddr(l, lastAccData.Address) theLog.ExtraData.StateList = append(theLog.ExtraData.StateList, wrappedStatus) + code := getCodeForAddr(l, lastAccData.Address) + theLog.ExtraData.CodeList = append(theLog.ExtraData.CodeList, hexutil.Encode(code)) default: //do nothing for other op code return diff --git a/core/vm/logger_trace.go b/core/vm/logger_trace.go index f348123237aa..87e75f0cd7e2 100644 --- a/core/vm/logger_trace.go +++ b/core/vm/logger_trace.go @@ -11,8 +11,8 @@ type traceFunc func(l *StructLogger, scope *ScopeContext, extraData *types.Extra var ( // OpcodeExecs the map to load opcodes' trace funcs. OpcodeExecs = map[OpCode][]traceFunc{ - CALL: {traceToAddressCode, traceLastNAddressCode(1), traceCaller, traceLastNAddressAccount(1)}, - CALLCODE: {traceToAddressCode, traceLastNAddressCode(1), traceCaller, traceLastNAddressAccount(1)}, + CALL: {traceToAddressCode, traceLastNAddressCode(1), traceContractAccount, traceLastNAddressAccount(1)}, // contract account is the caller, stack.nth_last(1) is the callee's address + CALLCODE: {traceToAddressCode, traceLastNAddressCode(1), traceContractAccount, traceLastNAddressAccount(1)}, // contract account is the caller, stack.nth_last(1) is the callee's address DELEGATECALL: {traceToAddressCode, traceLastNAddressCode(1)}, STATICCALL: {traceToAddressCode, traceLastNAddressCode(1), traceLastNAddressAccount(1)}, CREATE: {}, // sender is already recorded in ExecutionResult, callee is recorded in CaptureEnter&CaptureExit @@ -23,6 +23,10 @@ var ( SELFBALANCE: {traceContractAccount}, BALANCE: {traceLastNAddressAccount(0)}, EXTCODEHASH: {traceLastNAddressAccount(0)}, + CODESIZE: {traceContractCode}, + CODECOPY: {traceContractCode}, + EXTCODESIZE: {traceLastNAddressCode(0)}, + EXTCODECOPY: {traceLastNAddressCode(0)}, } ) @@ -50,6 +54,13 @@ func traceLastNAddressCode(n int) traceFunc { } } +// traceContractCode gets the contract's code +func traceContractCode(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error { + code := l.env.StateDB.GetCode(scope.Contract.Address()) + extraData.CodeList = append(extraData.CodeList, hexutil.Encode(code)) + return nil +} + // traceStorage get contract's storage at storage_address func traceStorage(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error { if scope.Stack.len() == 0 { @@ -89,17 +100,6 @@ func traceLastNAddressAccount(n int) traceFunc { } } -// traceCaller gets caller address's account. -func traceCaller(l *StructLogger, scope *ScopeContext, extraData *types.ExtraData) error { - address := scope.Contract.CallerAddress - state := getWrappedAccountForAddr(l, address) - - extraData.StateList = append(extraData.StateList, state) - l.statesAffected[scope.Contract.Address()] = struct{}{} - - return nil -} - // StorageWrapper will be empty func getWrappedAccountForAddr(l *StructLogger, address common.Address) *types.AccountWrapper { return &types.AccountWrapper{ @@ -122,3 +122,7 @@ func getWrappedAccountForStorage(l *StructLogger, address common.Address, key co }, } } + +func getCodeForAddr(l *StructLogger, address common.Address) []byte { + return l.env.StateDB.GetCode(address) +}