13.1 说明
分析源代码版本:master 2c87fd59(2019.3.7)
回头看 filecoin开发网络使用 中创建矿工,提交订单,支付等操作实际上都是actor的新增及状态改变
当前的实现vm还不具备通用abi数据的解释执行能力,未达到真正智能合约水平
13.2 exec(actor及vm的接口定义)
- 说明
- 提供可执行actor的最小接口要求 ExecutableActor (由actor及具体actor包实现)
- 提供actor键值存取接口定义 Lookup (由actor包实现)
- 提供状态临时存储的接口定义 Storage (由vm.Storage实现)
- actor的执行环境接口定义 VMContext (由vm.context实现)
- 具体源码注释如下
▼ package exec ▶ imports ▼ constants + ErrDanglingPointer + ErrDecode + ErrInsufficientGas + ErrStaleHead ▼ variables + Errors ▼+Error : string [methods] + Error() : string + ExportedFunc : func(ctx VMContext) []byte, uint8, error // actor符号集合 ▼+Exports : map[string]*FunctionSignature [methods] // 判断是否存在特定方法 + Has(method string) : bool // 对于单个函数的符号表 // todo中的事情:需要转换为非go类型 ▼+FunctionSignature : struct [fields] + Params : []abi.Type + Return : []abi.Type // 可执行合约接口,这是每一类型的合约必须实现的最小接口 // 包括account,miner,storagemarket,paymentbroker ▼+ExecutableActor : interface [methods] + Exports() : Exports + InitializeState(storage Storage, initializerData interface{}) : error // 由actor.lookup实现键值存储 (actor/storage.go) ▼+Lookup : interface [methods] + Commit(ctx context.Context) : cid.Cid, error + Delete(ctx context.Context, k string) : error + Find(ctx context.Context, k string) : interface{}, error + IsEmpty() : bool + Set(ctx context.Context, k string, v interface{}) : error + Values(ctx context.Context) : []*hamt.KV, error // 由vm.Storage实现 // 解决持久化的问题,有副本防止回滚机制 // 具体实现还有Flush持久化到datastore功能 ▼+Storage : interface [methods] // 提交最新actor Head + Commit(cid.Cid, cid.Cid) : error // 如下都为内存中操作 + Get(cid.Cid) : []byte, error + Head() : cid.Cid + Put(interface{}) : cid.Cid, error // actor的abi执行环境接口,由vm.context实现 ▼+VMContext : interface [methods] // 创建新的合约地址 + AddressForNewActor() : address.Address, error // 查询区块高度 + BlockHeight() : *types.BlockHeight // Gas收费 + Charge(cost types.GasUnits) : error // 创建合约 + CreateNewActor(addr address.Address, code cid.Cid, initalizationParams interface{}) : error // 判断是否为account类型的Actor + IsFromAccountActor() : bool // 合约中交易信息 + Message() : *types.Message // 执行合约函数 + Send(to address.Address, method string, value *types.AttoFIL, params []interface{}) : [][]byte, uint8, error + Storage() : Storage // 当Storage接口完成会删除如下两项 + ReadStorage() : []byte, error + WriteStorage(interface{}) : error
13.3 actor的类型及源码分析
- actor包定义及实现了基础actor,此外filecoin还定义了四种内置的actor类型
- 存储市场actor,此类actor整个网络只有一个实例,用于创建存储矿工、更新功率表、获取总存储容量
- Miner actor,此类actor整个网络只有多个实例(随用户数增加而增加),用于执行矿工相关的操作
- paymentbroker actor,此类actor整个网络只有一个实例,用于创建支付通道以及支付相关信息
- account actor,账户actor,此类actor整个网络只有多个实例(随用户数增加而增加),只能用于基本的转账操作
13.3.1 基础actor包
- 说明
- 定义了actor的基础结构,其中code如果使用内置的如上四种actor,他们的值都是固定的
- 提供了actor的基础操作方法
- 见笔者在代码中的注释
location: actor/actor.go ▼ package actor // Actor可以理解为合约或者账户,转账操作要检查code cid合法性 ▼+Actor : struct [fields] //余额 + Balance : *types.AttoFIL // 合约代码的cid,vm具体执行其对应的代码 // 1 具体代码的cid // 2 在go语言实现的四种特定合约,这个字段是常量,比如account,miner,storagemarket,paymentbroker + Code : cid.Cid // 合约状态的最新状态 + Head : cid.Cid // 防止重放攻击而设置的参数 + Nonce : types.Uint64 [methods] // 计算actor的cid + Cid() : cid.Cid, error // 打印合约信息 + Format(f fmt.State, c rune) // 增加Nonce+1方法 + IncNonce() // 编码 + Marshal() : []byte, error // 解码 + Unmarshal(b []byte) : error [functions] + NewActor(code cid.Cid, balance *types.AttoFIL) : *Actor ▼ functions // 只有account类型的actor使用 + NextNonce(actor *Actor) : uint64, error - init()
location: actor/export.go ▼ functions // 返回某个actor的方法执行函数 + MakeTypedExport(actor exec.ExecutableActor, method string) : exec.ExportedFunc // 序列化成字节切片 + MarshalValue(val interface{}) : []byte, error
13.3.2 storagemarket actor
- 主要功能
- 创建存储矿工
- 获取总存储量
- 更新功率
▼ package storagemarket ▶ imports ▼ constants + ErrInsufficientCollateral + ErrPledgeTooLow + ErrUnknownMiner ▼ variables + Errors + MinimumCollateralPerSector + MinimumPledge - storageMarketExports ▼+Actor : struct [methods] // 创建存储矿工 // 会调用到miner actor的创建 + CreateMiner(vmctx exec.VMContext, pledge *big.Int, publicKey []byte, pid peer.ID) : address.Address, uint8, error + Exports() : exec.Exports // 获取总存储 + GetTotalStorage(vmctx exec.VMContext) : *big.Int, uint8, error + InitializeState(storage exec.Storage, _ interface{}) : error // 更新功率 + UpdatePower(vmctx exec.VMContext, delta *big.Int) : uint8, error ▼+State : struct [fields] // miners合集的cid + Miners : cid.Cid + TotalCommittedStorage : *big.Int ▼ functions + MinimumCollateral(sectors *big.Int) : *types.AttoFIL // 实例化存储市场 + NewActor() : *actor.Actor, error - init()
13.3.3 miner actor
- 提供功能
- 有基本转账功能
- 提供如下功能
- filecoin网络中存在多个Miner Actor
▼ package miner ▶ imports ▼ constants + ErrAskNotFound + ErrCallerUnauthorized + ErrInsufficientPledge + ErrInvalidPoSt + ErrInvalidSealProof + ErrInvalidSector + ErrPublicKeyTooBig + ErrSectorCommitted + ErrStoragemarketCallFailed + MaximumPublicKeySize ▼ variables + Errors + GracePeriodBlocks + ProvingPeriodBlocks - minerExports ▼+Actor : struct [fields] + Bootstrap : bool [methods] // 增加订单 + AddAsk(ctx exec.VMContext, price *types.AttoFIL, expiry *big.Int) : *big.Int, uint8, error // 抵押承诺 + CommitSector(ctx exec.VMContext, sectorID uint64, commD, commR, commRStar, proof []byte) : uint8, error + Exports() : exec.Exports // 获取存储矿工相关信息 + GetAsk(ctx exec.VMContext, askid *big.Int) : []byte, uint8, error + GetAsks(ctx exec.VMContext) : []uint64, uint8, error + GetKey(ctx exec.VMContext) : []byte, uint8, error + GetLastUsedSectorID(ctx exec.VMContext) : uint64, uint8, error + GetOwner(ctx exec.VMContext) : address.Address, uint8, error + GetPeerID(ctx exec.VMContext) : peer.ID, uint8, error + GetPledge(ctx exec.VMContext) : *big.Int, uint8, error + GetPower(ctx exec.VMContext) : *big.Int, uint8, error + GetProvingPeriodStart(ctx exec.VMContext) : *types.BlockHeight, uint8, error + GetSectorCommitments(ctx exec.VMContext) : map[string]types.Commitments, uint8, error + InitializeState(storage exec.Storage, initializerData interface{}) : error // 提交时空证明 + SubmitPoSt(ctx exec.VMContext, postProofs []proofs.PoStProof) : uint8, error // 更新节点Id + UpdatePeerID(ctx exec.VMContext, pid peer.ID) : uint8, error // 报价单:价格,时长,序号 ▼+Ask : struct [fields] + Expiry : *types.BlockHeight + ID : *big.Int + Price : *types.AttoFIL // 矿工Actor状态 ▼+State : struct [fields] + Asks : []*Ask + Collateral : *types.AttoFIL + LastPoSt : *types.BlockHeight + LastUsedSectorID : uint64 + NextAskID : *big.Int + Owner : address.Address + PeerID : peer.ID + PledgeSectors : *big.Int + Power : *big.Int + ProvingPeriodStart : *types.BlockHeight + PublicKey : []byte + SectorCommitments : map[string]types.Commitments [functions] + NewState(owner address.Address, key []byte, pledge *big.Int, pid peer.ID, collateral *types.AttoFIL) : *State ▼ functions + NewActor() : *actor.Actor - init()
13.3.4 paymentbroker actor
- 说明
- 全网只有一个paymentbroker
- 几个概念的关系简图
- 源码分析注释
▼ package paymentbroker ▼+Actor : struct [methods] // 关闭支付通道 + Close(vmctx exec.VMContext, payer address.Address, chid *types.ChannelID, amt *types.AttoFIL, validAt *types.BlockHeight, sig []byte) : uint8, error // 创建支付通道 + CreateChannel(vmctx exec.VMContext, target address.Address, eol *types.BlockHeight) : *types.ChannelID, uint8, error + Exports() : exec.Exports // 增加资金 + Extend(vmctx exec.VMContext, chid *types.ChannelID, eol *types.BlockHeight) : uint8, error + InitializeState(storage exec.Storage, initializerData interface{}) : error // 查询某个支付者的信息 + Ls(vmctx exec.VMContext, payer address.Address) : []byte, uint8, error // 撤回资金 + Reclaim(vmctx exec.VMContext, chid *types.ChannelID) : uint8, error // 赎回(或者收款)资金 + Redeem(vmctx exec.VMContext, payer address.Address, chid *types.ChannelID, amt *types.AttoFIL, validAt *types.BlockHeight, sig []byte) : uint8, error // 收据,指明在特定区块高度之前都是有效的 + Voucher(vmctx exec.VMContext, chid *types.ChannelID, amount *types.AttoFIL, validAt *types.BlockHeight) : []byte, uint8, error ▼+PaymentChannel : struct [fields] // 支付通道内金额 + Amount : *types.AttoFIL // 已被赎回金额 + AmountRedeemed : *types.AttoFIL + Eol : *types.BlockHeight // 收款人地址 + Target : address.Address ▼ functions // 收据的签名及校验 + SignVoucher(channelID *types.ChannelID, amount *types.AttoFIL, validAt *types.BlockHeight, addr address.Address, signer types.Signer) : types.Signature, error + VerifyVoucherSignature(payer address.Address, chid *types.ChannelID, amt *types.AttoFIL, validAt *types.BlockHeight, sig []byte) : bool - createVoucherSignatureData(channelID *types.ChannelID, amount *types.AttoFIL, validAt *types.BlockHeight) : []byte - findByChannelLookup(ctx context.Context, storage exec.Storage, byPayer exec.Lookup, payer address.Address) : exec.Lookup, error - init() - reclaim(ctx context.Context, vmctx exec.VMContext, byChannelID exec.Lookup, payer address.Address, chid *types.ChannelID, channel *PaymentChannel) : error - updateChannel(ctx exec.VMContext, target address.Address, channel *PaymentChannel, amt *types.AttoFIL, validAt *types.BlockHeight) : error - withPayerChannels(ctx context.Context, storage exec.Storage, payer address.Address, f func(exec.Lookup) error) : error - withPayerChannelsForReading(ctx context.Context, storage exec.Storage, payer address.Address, f func(exec.Lookup) error) : error
13.3.5 account actor
- 说明
- 纯账户,记录nonce
- 只有转帐功能
- filecoin网络中存在多个account Actor
▼ package
account
▶ imports
▼ variables
-accountExports
▼+Actor : struct
[methods]
+Exports() : exec.Exports
+InitializeState(_ exec.Storage, _ interface{}) : error
▼ functions
// 实例化account actor 集成actor包中Actor所实现的所有方法
+NewActor(balance *types.AttoFIL) : *actor.Actor, error
// 将其他actor类型转为account,保留余额
+UpgradeActor(act *actor.Actor) : error
13.4 vm(虚拟机运行环境)
- 虚拟机执行函数
▼ package vm ▶ imports ▼-sendDeps : struct [fields] - transfer : func(*actor.Actor, *actor.Actor, *types.AttoFIL) error ▼ functions // 执行合约 + Send(ctx context.Context, vmCtx *Context) : [][]byte, uint8, error // 转账 + Transfer(fromActor, toActor *actor.Actor, value *types.AttoFIL) : error - send(ctx context.Context, deps sendDeps, vmCtx *Context) : [][]byte, uint8, error
- vm环境实现
▼+Context : struct [fields] - ancestors : []types.TipSet - blockHeight : *types.BlockHeight - deps : *deps - from : *actor.Actor - gasTracker : *GasTracker - lookBack : int - message : *types.Message - state : *state.CachedTree - storageMap : StorageMap - to : *actor.Actor [methods] // 实现上述VMContext 接口,注释见上 + AddressForNewActor() : address.Address, error + BlockHeight() : *types.BlockHeight + Charge(cost types.GasUnits) : error + CreateNewActor(addr address.Address, code cid.Cid, initializerData interface{}) : error + GasUnits() : types.GasUnits + IsFromAccountActor() : bool + Message() : *types.Message + Rand(sampleHeight *types.BlockHeight) : []byte, error + ReadStorage() : []byte, error + Send(to address.Address, method string, value *types.AttoFIL, params []interface{}) : [][]byte, uint8, error + Storage() : exec.Storage + WriteStorage(memory interface{}) : error [functions] + NewVMContext(params NewContextParams) : *Context ▼+NewContextParams : struct [fields] + Ancestors : []types.TipSet + BlockHeight : *types.BlockHeight + From : *actor.Actor + GasTracker : *GasTracker + LookBack : int + Message : *types.Message + State : *state.CachedTree + StorageMap : StorageMap + To : *actor.Actor ▼-deps : struct [fields] + EncodeValues : func([]*abi.Value) []byte, error + GetOrCreateActor : func(context.Context, address.Address, func() *actor.Actor, error) *actor.Actor, error + Send : func(context.Context, *Context) [][]byte, uint8, error + ToValues : func([]interface{}) []*abi.Value, error ▼ deps* : ctype [functions] - makeDeps(st *state.CachedTree) : *deps ▼ functions - computeActorAddress(creator address.Address, nonce uint64) : address.Address, error
- 合约状态存储
▼+Storage : struct [fields] - actor : *actor.Actor - blockstore : blockstore.Blockstore - chunks : map[cid.Cid]ipld.Node [methods] + Commit(newCid cid.Cid, oldCid cid.Cid) : error + Flush() : error + Get(cid cid.Cid) : []byte, error + Head() : cid.Cid + Prune() : error + Put(v interface{}) : cid.Cid, error - liveDescendantIds(id cid.Cid) : *cid.Set, error [functions] + NewStorage(bs blockstore.Blockstore, act *actor.Actor) : Storage ▼-storageMap : struct [fields] - blockstore : blockstore.Blockstore - storageMap : map[address.Address]Storage [methods] + Flush() : error + NewStorage(addr address.Address, actor *actor.Actor) : Storage ▼+StorageMap : interface [methods] + Flush() : error + NewStorage(addr address.Address, actor *actor.Actor) : Storage ▼ functions + NewStorageMap(bs blockstore.Blockstore) : StorageMap
13.5 state包(actor状态)
- 表征actor的状态