CaptureState logs a new structured log message and pushes it out to the environment CaptureState also tracks SSTORE ops to track dirty values.
(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error)
| 137 | // |
| 138 | // CaptureState also tracks SSTORE ops to track dirty values. |
| 139 | func (l *StructLogger) CaptureState(env *EVM, pc uint64, op OpCode, gas, cost uint64, memory *Memory, stack *Stack, contract *Contract, depth int, err error) error { |
| 140 | // check if already accumulated the specified number of logs |
| 141 | if l.cfg.Limit != 0 && l.cfg.Limit <= len(l.logs) { |
| 142 | return ErrTraceLimitReached |
| 143 | } |
| 144 | |
| 145 | // initialise new changed values storage container for this contract |
| 146 | // if not present. |
| 147 | if l.changedValues[contract.Address()] == nil { |
| 148 | l.changedValues[contract.Address()] = make(Storage) |
| 149 | } |
| 150 | |
| 151 | // capture SSTORE opcodes and determine the changed value and store |
| 152 | // it in the local storage container. |
| 153 | if op == SSTORE && stack.len() >= 2 { |
| 154 | var ( |
| 155 | value = common.BigToHash(stack.data[stack.len()-2]) |
| 156 | address = common.BigToHash(stack.data[stack.len()-1]) |
| 157 | ) |
| 158 | l.changedValues[contract.Address()][address] = value |
| 159 | } |
| 160 | // Copy a snapstot of the current memory state to a new buffer |
| 161 | var mem []byte |
| 162 | if !l.cfg.DisableMemory { |
| 163 | mem = make([]byte, len(memory.Data())) |
| 164 | copy(mem, memory.Data()) |
| 165 | } |
| 166 | // Copy a snapshot of the current stack state to a new buffer |
| 167 | var stck []*big.Int |
| 168 | if !l.cfg.DisableStack { |
| 169 | stck = make([]*big.Int, len(stack.Data())) |
| 170 | for i, item := range stack.Data() { |
| 171 | stck[i] = new(big.Int).Set(item) |
| 172 | } |
| 173 | } |
| 174 | // Copy a snapshot of the current storage to a new container |
| 175 | var storage Storage |
| 176 | if !l.cfg.DisableStorage { |
| 177 | storage = l.changedValues[contract.Address()].Copy() |
| 178 | } |
| 179 | // create a new snaptshot of the EVM. |
| 180 | log := StructLog{pc, op, gas, cost, mem, memory.Len(), stck, storage, depth, err} |
| 181 | |
| 182 | l.logs = append(l.logs, log) |
| 183 | return nil |
| 184 | } |
| 185 | |
| 186 | // CaptureFault implements the Tracer interface to trace an execution fault |
| 187 | // while running an opcode. |