状态

state是链上状态存储,比如A给B发起一次链上转账之后,A和B的账户余额信息都会存储下来。 以下我们把每个交易中的 所有对状态存储的操作 称作一个事务
state中事务具备原子性, 比如一个交易中一共有3个修改状态的操作,那么这3个操作要不然都能修改成功,要么都不成功。 举例如下:

func (a *A) DoTest(ctx *context.Context, env *ChainEnv) error {
    env.KVDB.Set(a, []byte("yu"), []byte("yu")) // 1. 修改状态

    err := DoOther()
    if err != nil {
        return err
    }

    env.KVDB.Set(a, []byte("qi"), []byte("qi")) // 2. 修改状态
}

上述代码中,一共有两处 修改状态 的操作, 如果代码在第一处执行成功, 但是在DoOther()这里执行出错返回,那么第二处的修改状态就无法完成了,此时 框架会一并把第一处的状态修改 取消掉 来保证原子性。

状态存储的组件名为StateStore,目前内部暂时只支持kvdb的存储形式。 状态存储 以区块为单位,按顺序依次执行每个区块内的事务都存入到数据库中。

代码在这里

func StartBlock(blockHash)

StartBlock()在区块链运行的 start block阶段调用,用来告知state当前的区块哈希。

func SetCanRead(blockHash)

SetCanRead()设置当前可以被读的区块中的状态。 一个区块交易执行完毕被存入链后,可能并不是立马就允许被读到的,尤其是finalize类型的链,需要 等到该区块被finalize之后该区块内执行的结果状态才可以被外界读到。 当然非finalize类型的链可以在区块被存进链后立马就被读到。

func Commit() (Hash, error)

Commit()提交该区块内所有事务,并返回该区块下的状态树的 stateroot

func Discard()

Discard()取消当前事务。

func DiscardAll()

DiscardAll()取消当前区块内所有的事务。

func NextTxn()

NextTxn()表示当前事务执行完,开始执行下一个事务。