evm7種重要指令的實現原理:
evm的所有指令定義都在core/vm/jump_table.go裡實現的,而每個指令對應的操作函式都是在core/vm/instructions.go裡實現的。
如果乙個節點併發呼叫智慧型合約,那麼對memory的操作是否有執行緒安全問題。不會,因為每執行乙個交易,都會建立乙個新的evm物件。只有最終寫入statedb的資料會有執行緒安全問題。
基本原理:乙個指令佔乙個位元組,也就是8為,16進製制從0x01到0xff,10進製從1到255。最多255個指令,如果加上0的話,就256個指令。evm執行指令的主要載體是棧。
棧裡的dup函式實現把棧上的某個值存入intpool中。
mload:花費32gas*資料大小,用途:取出棧頂的元素作為key,從memory中取出該key對應的value,存入initpoll中最新元素,並且把該值壓入棧中。
mstore:取出棧上的最新的兩個資料,乙個作為key,乙個作為value,寫入memory,並且存入initpoll中。initpoll也是乙個棧的結構
func opmload(pc *uint64, interpreter *evminterpreter, contract *contract, memory *memory, stack *stack) (byte, error)
func opmstore(pc *uint64, interpreter *evminterpreter, contract *contract, memory *memory, stack *stack) (byte, error)
// intpool is a pool of big integers that
// can be reused for all big.int operations.
type intpool struct
sstore:從棧中取中兩個值作為key和value,然後在statedb中存入剛才取出的key和value,並且在initpool中放入該value。
func opsload(pc *uint64, interpreter *evminterpreter, contract *contract, memory *memory, stack *stack) (byte, error)
func opsstore(pc *uint64, interpreter *evminterpreter, contract *contract, memory *memory, stack *stack) (byte, error)
實現的功能是:從位元組指令**資料中取出從pc計數器到x個指令出來,壓入棧中。x為1到32。
// make push instruction function
func makepush(size uint64, pushbytesize int) executionfunc
endmin := codelen
if startmin+pushbytesize < endmin
integer := interpreter.intpool.get()
stack.push(integer.setbytes(common.rightpadbytes(contract.code[startmin:endmin], pushbytesize)))
*pc += size
return nil, nil
}}
dump是轉存的意思,主要實現的是把棧中的某個元素壓入棧頂
具體實現的功能是:從棧頂開始算起,把棧上第x個元素存入intpool的棧頂,並且把該元素也存入棧的棧頂。
// make dup instruction function
func makedup(size int64) executionfunc
}func (st *stack) dup(pool *intpool, n int)
實現的功能是:把棧上的第x個元素和棧頂元素進行交換
// make swap instruction function
func makeswap(size int64) executionfunc
}func (st *stack) swap(n int)
實現的功能是:根據棧的前兩個元素作為key和size,從記憶體裡取出相應的資料,存入statedb的journal(日誌)裡。1,2,3,4代表的是日誌的主題,一次最多可以存入4個主題。
如果有多個主題,取資料的時候從data裡切分出不同主題的資料。
// make log instruction function
func makelog(size int) executionfunc
d := memory.get(mstart.int64(), msize.int64())
interpreter.evm.statedb.addlog(&types.log)
interpreter.intpool.put(mstart, msize)
return nil, nil
}}func (self *statedb) addlog(log *types.log)
(1) create指令實現的是建立合約,將會呼叫
res, addr, returngas, suberr := interpreter.evm.create(contract, input, gas, value)
(2)call指令實現的是呼叫合約,將會呼叫
ret, returngas, err := interpreter.evm.call(contract, toaddr, args, gas, value)
(3)callcode指令實現的是乙個合約呼叫其他合約,最終將會呼叫callcode方法,和call方法最大不同的是執行合約的上下文是呼叫者,而不是將要執行的合約。
ret, returngas, err := interpreter.evm.callcode(contract, toaddr, args, gas, value)
callcode一般發生在定義了多個合約,其中乙個合約呼叫了其他合約的方法。
(4)return指令實現的是:從記憶體中,以棧頂的前兩個元素作為偏移量和size,取出相應的資料放入intpool中,並返回資料
func opreturn(pc *uint64, interpreter *evminterpreter, contract *contract, memory *memory, stack *stack) (byte, error)
7種常見排序演算法的c 實現
今天心血來潮複習了一下基本的排序演算法,實現了一下,就順便發上來咯。在 裡做了注釋了 也就不多說了,直接上 吧。order algorithm.cpp 定義控制台應用程式的入口點。author netbin include stdafx.h include iostream include incl...
單例模式的7種實現方式
多個執行緒要操作同乙個物件,保證物件的唯一性,例項化過程只例項化一次 解決的思路 在載入類時就例項化乙個物件 public class singleton1 public static singleton1 getintance 特點用這個物件的時候才去例項化 public class hoonsi...
7種CSS實現垂直居中的方法總結
忽然發現自己已經有段時間沒有好好的複習下css布局了,有點慚愧啊 於是打算總結一下關於css垂直居中的7種方法。設定行高 line height 在css中,line height 屬性設定兩段段文字之間的距離,也就是行高,如果我們把一段文字的line height設定為父容器的高度就可以實現文字垂...