EOS智能合约开发(十五)EOS 状态机架构解析

article/2025/9/13 8:41:53

好久没有写文章了,最近公司事情比较忙。非常感谢上次杭州团队一位负责EOS状态机的同事精彩分享。今天查阅很多资料后,整理这篇文章,希望对大家有所帮助。

EOS状态机是什么?
简单讲就是数据库,是EOS记录智能合约执行结果的地方。

在 EOS 中,智能合约执行完毕后,所占用的内存会释放。程序中的所有变量都会丢失。如果智能合约里要持久地记录信息,比如游戏智能合约要记录每位用户游戏记录,本次合约执行完毕后数据不能丢失,就需要将数据存储到 EOS 数据库中。与数据库交互的 API 被官方成为 Persistence API,中文可以叫做持久化 API。下图说明了 EOS 智能合约在执行 Action 时,与数据库的交互过程。
这里写图片描述
为了方便智能合约与 EOS 数据库的交互,EOS 仿造了 Boost 库中的 Multi-Index Containers,开发了 C++ 类:eosio::multi_index(以下简称 multi_index),中文可以叫做多索引列表类。

multi_index 头文件地址:
https://github.com/EOSIO/eos/blob/master/contracts/eosiolib/multi_index.hpp

在 EOS 见证人硬盘中,为每个账户都预留了数据库空间(大小与代币持有量有关),每个账户名下可以建立多个数据表。智能合约无法直接操作存储在见证人硬盘中的数据表,需要使用multi_index作为中间工具(或者叫容器),每个multi_index实例都与一个特定账户的特定数据表进行交互(取决于实例化时的参数)。EOS智能合约与EOS数据库的数据交互如下图所示。
这里写图片描述
数据表
multi_index是一个非常方便的数据库交互容器,可以存储任何C++数据类型。每一个multi_index都相当于传统数据库的一个数据表(table),但将传统数据库的行与列的形式改为了单纯的列。也就是说multi_index是一个线性排列的表,只有一列,每一行都只存储一个对象。但是一般来说multi_index存储的对象都是结构体或者类,里面含有多个成员变量,所以multi_index存储数据的灵活性也是不亚于传统数据库的。

我们使用官方的“汽车维修店”示例,我们建立一个数据表,储存每个汽车维修店客户的账户名、保养时间、车辆里程。那么multi_index数据表储存的项目中,每个都是如下的结构体:

struct service_rec {uint64_t        pkey;           // 主键account_name    customer;       // 车主用户名uint32_t        service_date;   // 维修保养时间uint32_t        odometer;       // 车辆里程
};

在传统数据库中,需要建立一个4列的数据表,用来储存每个用户的这个4个数据,而multi_index的每个数据表只有一列,只存储每个用户的 service_rec 整个结构体即可。下图为multi_index数据结构。
这里写图片描述
多索引
首先,每个数据表要有一组主键,主键必须是无符号 64 位整数类型(64-bit integer),这就是上面的service_rec结构体中第一个变量为uint64_t类型的原因。在数据表中,所有的对象就是按照主键升序排列的,小的在前,大的在后。主键可以是有意义的,也可以是没有意义的,让系统产生一个在这个数据表中没有被使用的主键即可。为了设置主键,我们需要在之前的service_rec结构体添加一个叫做primary_key()的成员函数函数的返回值为主键。

auto  primary_key() const { return pkey; }

这样就将pkey这个变量设置成了主键。

multi_index从字面上看就是能使用多个索引的数据表。EOS 中,每个multi_index或者说每个数据表都可以设置最多16个索引。索引相当于使用特定的方式给数据表中的对象重新排序。比如在我们经常使用的 windows 文件管理器中,可以按照文件名排序、按照文件修改时间排序、按照文件大小排序,这就有了3个索引。EOS数据库索引更加灵活,可以单独按照结构体中的某个变量索引,也可以将变量之间的运算结果(函数输出)进行索引。如果我们想使用车主用户名进行索引,需要在结构体中添加一个get_customer()成员函数,函数的返回值为索引变量。

account_name    get_customer()const { return customer; }

这样就将customer这个变量设置成了数据表的一个索引,下图右侧为customer索引。
这里写图片描述
迭代器
multi_index是如何操作数据表中的每个对象的呢?答案是 Iterators(迭代器)。大家可以搜索 “C++ 迭代器”或者设计模式中的“迭代器模式”来了解迭代器的设计思路。在 EOS 数据库中,我更愿意将迭代器比喻为一个“电梯”,在整个数据表中上下穿梭。所有对数据的操作必须通过迭代器完成。典型的数据修改过程是这样的:首先使用迭代器的find()方法,在特定的索引中寻找需要的数据,比如在车主用户名索引中寻找某个用户。迭代器会移动到需要的数据对象上。然后就可以使用迭代器的modify()方法修改当前迭代器对应的数据。下图为迭代器指向用户 Sue 的情况。
这里写图片描述

2018年8月29日整理于深夜。


http://chatgpt.dhexx.cn/article/BqIw8AeA.shtml

相关文章

接口测试时,输入所有参数的参数值后,接口返回“参数错误:所有参数都不能为空”

问题原因: 参数名称输入有误,前台(pwd)和后台(password)的参数名称不一致 ,保持一致后即可

matlab 错误使用 connector.internal.autostart.run输入参数的数目不足。

matlab打开后提示: 错误使用 connector.internal.autostart.run输入参数的数目不足 原因:自己写的一个函数和matlab自带的函数重名了 参考:警告: 在 matlabrc 中初始化 Java 首选项失败 – MATLAB中文论坛MATLAB中文论坛MATLAB 基础讨论板块…

Matlab 自带遗传算法函数 ga() 运行报错:“ fitnessfcn() 输入参数的数目不足。”

原始程序 %主程序 m [1 2]; R [1.5 1]; epsilon [2^R(1)-1 2^R(2) - 1]; A [-1 epsilon(1); 0 -1]; b [0 0]; Aeq [1 1]; Beq 1;%matlab自带函数包 [x_optimal, fval] ga(fitnessfcn, 2, A, b, Aeq, Beq, [0;0], [1;1], []); ---------------------------------…

matlab函数参数不足,调用函数显示输入参数不足

问题描述.png (29.7 KB, 下载次数: 1) 2015-1-27 09:34 上传 %Gauss-Newton算法实现如下 function[x,minf] = GN(f,x0,var,eps)formatlong; ifnargin == 3 %如果没有设置eps,则eps=1.0e-6eps = 1.0e-6; end m = 0; S =transpose(f)*f; %trnspose是转…

matlab 函数不定参数,matlab function定义一个函数,但一直出来说输入参数数目不足。我用的是2014版本,不知道数目原因啊?...

www.mh456.com防采集。 h 5;g 1; % g取源0有问题% 被积函数2113可以化5261简成f 4102(a,b,r)(r*h-r^16532*cos(a-b))/(h^2r^2g^2-2*h*r*cos(a-b))^1.5;% 求积分quadv((r)quadv((b)quadv((a)f(a,b,r), 0, 2*pi), 0, 2*pi), 0, h) 错误在于,调用函数f( x )缺一个…

matlab plot输入参数太多,输入参数太多问题

版本:R2016a 利用SCE-UA调用新安江模型进行率定时,显示参数太多,求大神指导。 clear; clc; spathcd P0(textread([spath,\matlabxingshanjiangyu.txt])); PP0(2,:);%降水量(mm) EI0(textread([spath,\matlabxingshanzhengfa.txt])); EIEI0(2,…

参数输入太多

参数输入太多 在向platEMO平台添加新的算法时,可能会出现参数输入太多的错误提示 可能是由于输入的参数内包含逗号,比如 a[1,2],b[3,4] 从而造成”输入参数太多“的错误提示。

MATLAB S-function(教程分享) 报错 flag = 3(output), at time 0.0. 输入参数的数目不足。

前言 从上周开始用S-function做仿真,之前已经学过的,我觉得很好的教程网址是 【0基础直接带你上手matlab simulink仿真(不是标题党,讲解超级细致用心)(非线性系统自适应控制器的搭建)】 https…

matlab报错“输入参数的数目不足”

图片源自下方链接 原文链接MATLAB中出现参数数目不足的错误提示 - 爱上对方过后就哭了忆 - 博客园 (cnblogs.com)

错误使用 max 输入参数的数目不足。

相比大多数人熟悉的在调用自己编写的函数时出现的 “输入参数的数目不足” 问题,该情况下(即在同一脚本或同一函数中)也会出现matlab内部函数调用问题(如max、min等),在编程时应注意此点!

Matlab运行自定义函数显示“输入参数的数目不足”

问题描述 很多初学者在刚开始学习使用Matlab自定义函数时,可能遇到程序上没有问题,但一运行就显示输入参数的数目不足这个问题。 比如自定义一个函数:查找最小的m,使得m满足12…m > k(k为任意一个整数)…

浏览器播放视频倍速方法

1.右击播放页面 2.选择检查 4.选择console,如图: 5.在下面输入 :videojs.getPlayers("video-player").html5player.tech_.setPlaybackRate(1.5),括号里的数字就是要加倍的倍速。

浏览器播放RTSP

浏览器播放RTSP 由于现在浏览器不直接支持RTSP,然后很多监控厂商如海康大华等又不提供RTMP的情况下,项目需要实现HTML中播放监控视频。之前做过转流的方案,在服务器中把RTSP转成RTMP,这种方案开发量大而且转码不稳定,…

0516---win10 chrome 浏览器播放视频没有声音的解决办法

win10 chrome 浏览器播放视频没有声音的解决办法 近期我的Win10 主机在使用 Chrome 浏览器播放搜狐视频的时候没有声音,而用 Edge浏览器播放同一视频就一切正常,初步判断是浏览器的设置引起的。通过以下操作步骤得以解决。 启动 chrome 浏览器&#xf…

html5播放mp4不见画面,浏览器播放mp4格式视频时只有声音看不到画面的原因及解决方法(精)...

做HTML5网页,要播放视频,视频格式为mp4,结果浏览器只能听到声音,看不到画面。 反复测试,多个浏览器均出现此问题。刚开始以为视频的格式不对,我是从MOV转的MP4格式,反复确认嵌入的视频确实是mp4…

360浏览器html5无法播放,win7系统360浏览器播放不了视频的解决方法

今天和大家分享一下win7系统360浏览器播放不了视频问题的解决方法,在使用win7系统的过程中经常不知道如何去解决win7系统360浏览器播放不了视频的问题,有什么好的办法去解决win7系统360浏览器播放不了视频呢?小编教你只需要 1、视频无法正常…

《浏览器播放RTSP方案》之 VLC插件播放RTSP视频流

VLC插件播放RTSP视频流 多版本chrome安装安装vlc软件开启浏览器的NPAPI设置编写测试页插件设置其他问题最后 目前网页对于RTSP流直接播放不支持,目前有插件和转流两种方式,这里针对vlc插件播放做一个简单的梳理。 查看官网教程 vlcWebPlugin, 得知其浏览…

浏览器播放rtsp视频流:4、jsmpeg+go实现局域网下的rtsp视频流web端播放

文章目录 1.前言2.资料准备3.兼容性及适用性说明4.jsmpeg架构5.基于以上架构的go方案可行性分析6.编译和结果展示(编译坑点)7.最后 1.前言 之前的rtsp转webrtc的方案存在如下缺陷:1.只支持h264;2.受限于webrtc的理解难度以及搭建…

浏览器播放RTSP摄像头视频

一、项目需求,需要在chrome浏览器中播放rtsp协议的摄像头视频流 二、思路: 1、chrome已经不支持插件了,所以排除一切插件的思路; 2、浏览器目前停留在支持rtmp协议,hls协议流视频阶段,还没开始支持rtsp协议…