0%

为 C++程序写 rustbinding

AutoCxx 与 CWrapper+Bindgen

为 c++程序写 ruts-binding

在代码的世界中,还是 c和 cpp站绝大多数,现在提一个比较常见的需求:提供一个 c++的程序,最终需要再 rust中调用 c++程序提供的接口。

一般来说有两个方法

  1. 直接使用 cxx autocxx为 rust代码生成一份 unsafe的代码,然后直接调用
  2. 第二种方法比较路径稍长,先针对 c++代码的 header 写一份 c风格的头文件cwrapper,然后针对 c的头文件写一份 c头文件的实现。接下来编译自己的cwrapper,生成一份新的动态库。接下来使用 bindgen 根据 cwrapper生成一份 unsafe rust。最后在 rust代码中调用。

总体来说 cxx 或者 autocxx 可能性能会更好一些,但是 autocxx并不能搞定一切。第二种方法胜在稳定,毕竟 c的 abi比较稳定。本文将采用后一种方法。

速成材料

技术基础是:会 rust,不会 c++或者 c。所以需要速成,了解 c和 c++。如果彻底不会 c++,写 bingen 无从谈起。

下面是一些材料

阅读全文 »

solana合约学习

本文是对 solan相关问题介绍,主要用于记录solana合约的学习过程。因为现阶段还没有十分深入的学习 solana的细节,所以目标限定在 solana的简单合约编写,环境搭建,测试。

基础

因为是学习指南,所以会先强调学习的基础。本文的基础建立在会 rust基础上,明白 rust的语法,可以达到 rust编写简单代码的基础之上。因为 solana 合约是直接使用 rust编写的。如果不具备简单的 rust基础,请先学习 rust book,至少了解 rust的基本语法。

solana环境

因为 solana有自己的介绍文档,不再重复介绍solana概念。下面主要讲剩余部分。

  1. 开发环境
    1. 主要就是 rust环境,可以去 rust官网上直接安装 rust环境。因为 rust已经比较成熟,没有特别的问题,直接安装最新环境。
    2. 编辑器,因为是直接使用 rust开发solana 合约的,所以主流的 VSCODE Rustrover vim zed emacs都可以。选择自己喜欢的就好。
    3. solana cli工具。https://solana.com/developers/guides/getstarted/local-rust-hello-world
    4. cli工具是生成地址,链接 solana节点,部署合约的基础。后面会继续提到一些注意事项,请务必参考安装的的注意事项。
    5. anchor anchor是 solana 的“框架”,可以去 anchor官网安装 solana框架。后面也有注意事项。
    6. 以上的套件理论上是全部需要的。如果你只是使用solana native开发,可以不使用 anchor。也就可以不用安装 anchor 套件。

环境安装中的特殊问题

  1. 根据目前 2024年06月08日20:17:14 时间 solana 是 v1.18.15。 solana 本身并不是直接安装最新版本就好了。最新版本可能出现编译不过,获取有一些更加具体的字节超量的编译问题。这时候就需要回退到历史版本。可以看下面的链接。当然如果你非常幸运,安装之后完全没有问题就不必折腾。事实是,我安装了最新版之后一直无法通过编译,然后不得不安装下面的方案回退。
  2. https://www.notion.so/alvinvip/cd22ecfe315d4acbb83c68ca8a3d7b30?pvs=4#14fa26df7432402ebf18529fecf20e40
  3. anchor也存在以上问题,最新版无法运行。这样采用上面的办法即可,直接退版本。
  4. https://book.anchor-lang.com/getting_started/installation.html
  5. 注意查看版本关系 anchor 0.30需要使用最新的 solana v1.18.15(务必注意时间,后续升级必须兼顾 solana版本和 anchor版本)

测试问题

阅读全文 »

REVM代码阅读 02

前文介绍

在 01章节,对阅读 revm做了一些预先的准备工作,主要包括了解solidity语言,学习 OPCODES以及自顶向下了解 evm的基本结构三部分。其中第三部分最好大致实现征战虚拟机栈的运行过程加深理解。现在开始阅读 revm代码。阅读代码的过程比较枯燥,请保持耐心。

针对单独实现的 evm不在少数,使用 rust编写的 evm也不是唯一的。有下面的两个

https://github.com/rust-ethereum/evm

以上是 rust-ethereum名下的 evm项目,他是 parity名下的项目,在项目中提到 polkdot项目就使用该虚拟机。

另外一个就是我们看的 evm revm

https://github.com/bluealloy/revm

也有众多的以太坊生态项目使用该虚拟机。该项目拥有一本 books来介绍虚拟机的设计思路。在初步阅读代码之前,我们先阅读文档来了解 revm的整体设计思路。

https://bluealloy.github.io/revm/

阅读全文 »

REVM代码阅读 01

经过一些时间的准备,现在进行 REVM代码的阅读

准备环节

这些准备主要包括一下的方面

  1. 速览 《精通以太坊》,有一个全局的认识
  2. https://github.com/WTFAcademy/WTF-Solidity 通过这些资料来了解 solidity的语法。我的标准是学习完上面的课程并且完成习题,通过认证。
  3. https://www.wtf.academy/docs/evm-opcodes-101 通过这些资料来学习以太坊的操作码 OPCODE, 因为不会 python, 所以使用 rust实现了其中其中的逻辑。可以参考这个链接https://github.com/TigerInYourDream/naive\_evm 。主要需要跑通其中的用例(执行其中的 bytecode)。(至少做完 101 和 102)

做出了以上的准备之后,可以对以太坊虚拟机有一个整体性认识。其中改的代码可以参考上面的链接阅读。

总体概览

经过以上的准备,对以太坊虚拟机有了一个感性的认识。从最简单的模型,以太坊虚拟机就是一个栈的数据结构,每次把b solidit编译成对应的 bytecode,然后拆分成一个又一个的 op code。把 op code按照栈的方式一次执行就完成了“虚拟机”的工作。

下面图来自于 WFT Academy的 op code 101教程,从高层次展示了以太坊虚拟机的结构

https://image-bucket-for-alvin.oss-cn-beijing.aliyuncs.com/img/evm\_overview.png

阅读全文 »

diesel使用的一些小知识点

最近因为使用diesel,大致看了diesel的文档同时结合自己两天内写代码的经验,总结出下面几条要点,作为参考。严格来说,这些知识点比较琐碎不能够成为一篇文章,但是想到可以为自己以后使用diesel作参考还是写出来。

  1. 设置好.env之后 diesel setup 是创建数据库的

  2. diesel migration generate create_posts 最后一个参数是创建migration的文件夹名的 它会生成一个带时间的migration文件 里面有个up和down的sql up 里面负责创建数据库表的 down 里面负责撤回车操作的

  3. up 和 down 里面的sql要自己创建

  4. diesel migration run 执行migration里面的up.sql的操作的 确切的说就是建表 5. diesel migration redo 执行migration里面的down.sql的操作 确切的拉说是删除表

  5. 注意了 setup是会创建数据库和直接运行migration run中的建表数据的 但是如果数据库存在是不会运行的。如果在 migration中添加,后续这个也是不会运行的

  6. 这一步进行之后schema文件也会生成。这个文件是可以改的 ,但是不建议改

  7. 如果升级数据库,请使用新的migration文件

  8. 注意使用extern crate diesel 和#[marco use],不然schema下的东西又是找不到的

    以上的条目中需要补充的还有如下

    本来以为在rust2018版本以后,就完全不使用extern crate了。但是事实证明还是需要extern crate diesel和#[marco_use]的,不然会有很多东西找不到

    使用diesel尽量引入prelude::* 虽然我不喜欢这样引入,但是自己精确引入会很麻烦

    一定要注意schema文件

如果使用只是使用diesel查询和写入如何简化代码

这个问题会显的很奇怪,因为作为一个ORM,本来就是辅助我们进行增删改查的。其实我们看了diesel的官方指引之后就会觉得这个问题很合理。重新表述如下

根据diesel的官方指引,我们是用建立连接,建立数据库,设计表这几个步骤一路走下来的。实际上,大多数时候,数据表并不是我们建立的。我们只需要使用diesel的库,连接数据库CRUD即可。这种情况下,如何简化操作呢?

根据我的尝试大致需要如下

  1. 引入库,这个是必须的

  2. 设置sql路径,这个是必须的

  3. 无需diesel setup因为我们不需要建立数据库,数据库是存在的

  4. 无需diesle migration run 因为表也不是我们建立的。

  5. 没有建表,没运行diesel migration run,则diesel不会为我们自动建立schema.rs文件,也不会在schema.rs中生成table宏的语法。所以我们需要手动去建立schema.rs的文件,src/schema.rs。就是必须建立的在src路径下面。这样才不会出错。然后我们在schema.rs中手动写入 table!宏。这样才可以正常使用。

  6. 以上的步骤是可以正常使用的,也是文件最少的情况。还有下面的情况补充

    如果我们运行了diesel set 如果数据库存在,是不会建立数据库的。会产生一个migrations文件。一个和Cargo.toml同级别的diesel.toml文件,里面配置了schema.rs文件的位置。 所以上一步中如果不运行diesel set,需要我们手动把schema文件放在指定的位置。

    同时,因为我们 不建表,所以不运行diesel migration run。schema里面是空的,为了正确使用orm的方便特性,我们得去手动补全这个文件,自己写table!宏。当然这个很容易。看example即可

    一些零碎的知识,其他的正常使用参考文档即可。这个算是在文档之外的补充备查!

阅读全文 »

占星与星座计算 morinus house system

在系列前三节,已经基本介绍了和占星有关的模型,基本的分宫制的原理和占星以及天文中所出现的术语,这一节将带大家进行一次实际的占星计算。本文仅涉及星盘的计算,不涉及其他。

本文的重点是星盘的计算。本文将采用莫林分宫制morinus house system!至于为什么选择莫林分宫制,是因为莫林分宫制可以找到具体的数学计算公式,便于计算。且莫林分宫制在高纬度地区受到的扭曲小。至于分宫制的基本原理,可以查看上一节分宫制基本原理。

对于“morinus house system”是有专门的计算方法,通过一系列的加减乘除算出一个人出生时的MC、Asc以及每个宫头所在得度数,就可以排出一个近乎完整的星图了。

ASC:东升点是在诞生时刻在诞生地点的东面地平与黄道交接的一点

MC:天顶

我们在计算的时候需要以下参数

  1. 当事人的出生位置,需要从具体地点转化成经纬度
  2. 出生时间,需要转化为恒星时
  3. 黄赤交角,这个是固定值。关于黄赤交角可以看第一节天球部分。23°27′
  4. 以及如下公式

MC = arctan(tan(RAMC) / cos(e))

RAMC为上中天的赤经度数

阅读全文 »

占星与星座计算 儒略历和恒星时计算

在前两节的文章基础之上,我们开始进行真正的计算。在介绍计算星盘之前,我们需要一个预先准备的数据。儒略历和恒星时。网上的现成代码似乎没有说的很清楚,公式不够统一,结果也难以验证,为此参考了很多资料。其中有两个资料确定是对的。

https://zh.wikipedia.org/wiki/恒星时

上面公式中关于儒略历的转化公式是正确的,请注意其中的高斯符号。高斯符号相当于代码中的floor()函数。

后面关于恒星时的计算不确定正确性。

然后参考一份关于天文算法的论文,或者是一本翻译的PDF。感谢“冯剑和他的译友”翻译了这本天文算法,使我得到了确切的公式。

关于什么是恒星时可以也可以参考上面的wiki。

关于结果,分别得到了多项式T,算出来以角度为单位的恒星时,以时间hour为单位的恒星时,以时分秒为单位的恒星时。

现在公历纪元的年表示为Y、月为M、日为D、时为h、分为m、秒为s,1月、2月分别当做上一年的13月、14月。(例:2010年1月1日时Y=2009, M=13, D=1),然后求出儒略日

计算儒略历请注意以上的重点。

阅读全文 »

占星与星座计算 黄道十二宫与分宫原理

在占星与星座计算的第一篇文章中,尽可能详细的介绍了天球的构建过程原理和相关的概念。这一节我来介绍何为黄道12宫以及分工制的基本原理,不涉及具体分宫制。

黄道带

上一节的天球示意图中,我们已经标注出来了黄道,就是假定地球不动,太阳绕地球运动所形成的面,就是黄道。因为地球自转和地球公转是有一定角度偏差的。所以黄道和赤道是有一个23.5度的夹角的。

黄道带(或是黄道十二宫)的概念起源于巴比伦占星术,巴比伦人注意到了与太阳同时升起的星星,在黎明之前,可以观察到靠近太阳位置的星星升起,这些星星以一个似乎规则的圆周来回运动。他们将这些星星分为十二组,并给其命名。希腊人从巴比伦人那里继承了这一习惯,才有了黄道十二宫,这个词来源于希腊文zodion,意为“小动物”。

具体的黄道带的概念如下

黄道带(希腊语:ζῳδιακός, zōdiakos),是天文学的名词,指的是在黄道上的星座组成的环带,不仅是太阳每年在天球上所行经的路径,月球和行星的路径也大略都在黄道的附近,因此也全部都在黄道带的星座内。 在占星术,黄道带被人为划分为十二个随中气点移动(与实际星座位置不一致)的均等区域,各自都有符号。 因此,黄道带是一个天球坐标系统,或是更具体的说是一个黄道坐标系统,以黄道做为纬度的基准平面(原点),并且以太阳在春分时的位置作为经度的原点

黄道12宫的顺序如下

白羊宫(Aries, ♈︎);
金牛宫(Taurus, ♉︎);
双子宫(Gemini, ♊︎);
巨蟹宫(Cancer, ♋︎);
狮子宫(Leo, ♌︎);
处女宫(Virgo, ♍︎);
天秤宫(Libra, ♎︎);
天蝎宫(Scorpio, ♏︎);
射手宫(Sagittarius, ♐︎);
摩羯宫(Capricornus, ♑︎);
水瓶宫(Aquarius, ♒︎);
双鱼宫(Pisces, ♓︎)。

古人观察星空,发现天体分作两类:一类固定在天球上,组成各个星座,形成一幅永恒的天空背景,称之为恒星;另一类天体在黄道附近运行,不断穿过黄道上的十二个星座(或中国的二十八宿),称之为行星。这些行星包括七颗(七曜),分别是阴阳——太阳和太阴(月球),以及五行——金木水火土五个肉眼可见的经典行星。太阳在黄道上一年运行一圈,太阴在黄道上一个月运行一圈。一定要注意,占星中的行星和实际的行星概念并不一致,这毕竟是古代天文学。由于整体一环为360度,所以每个星座占据了360/12 = 30 度。

阅读全文 »

占星与星座计算 天球

最近因为某些原因,有了一段空余的时间。当你空闲便有了一些奇思妙想。因为很多年前特别喜欢一个关于星座的故事,所以利用这一段空余时间写一个系列文章讲占星中的一个小知识。为了不使文章引起争议,特此声明:本人完全相信星座!不解释。文章的前面系列介绍和占星有关的天文基本概念,后面具体根据人的出生时间,地理位置(经纬度)来计算人的星座。可能读了这一系列的文章,大家可以更好的理解为什么星座归类于“占星学”,这样一个听起来非常正式的名字。另外因为不是撰写论文,本文不会详细列出各类依据。太累!

天球概念

天球示意图

以上图片为完整的天球示意图

和地球概念相对,古代天文学家提出了天球的概念。天球是一个想想的球体,他也是旋转的。理论上具有无限大的半径且和地心是同心的。如图所示:和地球有赤道和南北极的概念对应,天球也有对应的天球赤道和天球南北极。

古代天文学家认为我们和星体是等距离的,尽管这并不正确。因为古代缺乏有效的天文观测手段。星球不是靠我们肉眼就可以判断出距离的。古代科学家克服了这种距离上的因素,使用角度来确定星球在天空中的位置。在当时观测条件受限的情况下,不失为一种很有效的天文抽象系统。

地球会围绕地轴自转,相对应于地球不动的参照系下。天球也会围着天极旋转,24小时不停。这就形成了古代天文学家的眼中的昼夜交替原理。太阳,卫星,形星都是东升西落的,这种称为天球的周日实视运动。地球因为有其公转,一颗横行总是比前一天提前(约4min)上升。

和地球对应的概念一样,天球也有自己的南北半球,对应也有南北回归线,南北极

北回归线:北回归线是太阳在北半球能够垂直射到的离赤道最远的位置点,将该点之纬度线便叫“北回归线”,在公元2018年,其位置约在北纬23°26′11.3″ (或 23.43648°)。相反,南纬23°26′11.3″ (或 23.43648°)则为“南回归线”。

阅读全文 »

比特币pow难度验证

何为POW

pow的全称为proof of work,即工作量证明。简单的解释为“做了多少工作”。抛开区块链的背景,pow就是对自己做了多少工作的一种说明:比如做了学习了50个小时的汽车驾驶。而他人很容易验证这个结果:你可能50个小时之后拿到了一本驾照。别人就知道你确实在学习驾驶上使用了50个小时。

Block Header

在区块链的世界里,pow的数据可以体现在区块链的区块头中。当然一般来说,讲解POW的难度离不开挖矿问题。本文因为主要讨论方向的问题,不展开讲挖矿,主要从区块头入手。在阅读下面的内容之前,默认读者已经有了如下前置知识

  1. 区块链常识
  2. 比特币基本概念
  3. 挖矿基本概念

抛开前置知识之后,我们来看区块头的数据结构。

https://en.bitcoin.it/wiki/Protocol_documentation#Block_Headers

可以直接参考以上链接,当然可以可以直接查看比特币的源码,我们现在把数据列出来。

1
2
3
4
5
6
7
8
struct header_structure {      // BYTES   NAME
uint32_t nVersion; // 4 version
uint8_t hashPrevBlock[32]; // 32 previous block header hash
uint8_t hashMerkleRoot[32]; // 32 merkle root hash
uint32_t nTime; // 4 time
uint32_t nBits; // 4 target
uint32_t nNonce; // 4 nonce
};
阅读全文 »