2

太上中的基因设计与Binary | 函数式与区块链(一)

 2 years ago
source link: https://learnblockchain.cn/article/2805
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
太上中的基因设计与Binary | 函数式与区块链(一) | 登链社区 | 深入浅出区块链技术

太上中的基因设计与Binary | 函数式与区块链(一)

let's Code with Function

关于函数式编程:

函数式编程是有别于传统的面对对象范式的编程范式,函数式方向是目前编程语言发展的大方向,所有新设计的编程语言都或多或少的引入了函数式编程功能。

笔者认为,「下一代计算机学科体系」将基于函数式编程语言。因此,打好函数式编程基础对于具备「长期主义」思维的程序员是必要的。

关于本专栏:

本专栏将通过实战代码分析与经典著作解读,分享作者关于函数式编程与区块链的思考与实践。就目前而言,本专栏将基于两种函数式语言:Rust 和 Elixir,有时候会提及其它语言,作为辅助性参考。

关于太上:

太上是笔者团队近期实践的一个函数式+区块链的项目。

太上炼金炉在不改变原有 NFT 合约的基础上,通过附加「存证合约」,赋予 NFT 组合、拆解、生命周期、权益绑定等能力,锻造 NFT +,创造无限创新玩法与想象空间。

项目地址: https://github.com/WeLightProject/Tai-Shang

愿景0x01: 助力所有 NFT 及其相关项目,让其具备无限商业想象空间与无限玩法。

愿景0x02: 成为下一代区块链基础设施

太上是本系列用以探讨函数式编程的第一个项目。

Binary 基础知识

什么是 Binary? Binary 中文为二进制类型,是一种各编程语言中都存在的基本数据类型,在部分语言(如Python)中,将其称之为 Bytes。

Binary 可以看做是 0-255 的整型构成列表(List),如:<<255,18,33>>

Binary 和字符串(String)是什么关系? 字符串是 Binary 的子集,字符串能转化为 Binary,但不是所有的 Binary 都能转化为String。

Binary 在区块链中有哪些应用?

在区块链中随处可见 Binary 的身影,如私钥(Privkey)、公钥(Pubkey)、地址(Address)均可以表现为

Binary 的形式;智能合约编码后是 Binary;签名(Signature)也是 Binary。

不同语言中的 Binary

虽然在本质上等价,但是在不同语言中 Binary 会呈现不同的形式。

Python:

>> payload = bytes('你好 世界', encoding='UTF-8')
>> print(payload)
b'\xe4\xbd\xa0\xe5\xa5\xbd \xe4\xb8\x96\xe7\x95\x8c'

Java:

class BytesDemo
{
	public static void main(String[] args)
	{

		byte payload[] = new byte[3];
		payload[0] = (byte) 0x0A;
		payload[1] = (byte) 0xFF;
		payload[2] = (byte) 0x01;

		for (byte theByte : payload){
  			System.out.println(Integer.toHexString(theByte));
		}
	}
}

NodeJs:

> var payload = new Buffer('hello world')
> Buffer.prototype.toByteArray = function () {return Array.prototype.slice.call(this, 0)}
> payload.toByteArray()
[ 104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]

Rust:

let shift_jis = b"\x82\xe6\x82\xa8\x82\xb1\x82"; // SHIFT-JIS 编码的 "ようこそ"

Elixir:

iex> <<11,22,33,44>>

万变不离其宗。我们要认识到,本质上来讲这些 Binary 都是一样的。

太上中的基因设计

太上中的基因,是对于价值容器(NFT)承载的属性的一种抽象表达。具体渲染出来的实体,不管是渲染出一只猫还是一把屠龙宝刀,这事和基因本身是解耦的。

因此,笔者设计了这样的 Binary 模型:

Gene
<<33, 44, 66, 22, 11, 55, 234, 111>>
  |---|   |---------------------|-----           
    |                                |
前1/4处用以表示二值属性,如男/女      后3/4用以表示数值属性,如魔法值

在处理 Gene 的时候,函数式编程中的 「Pattern Match」(模式匹配)就表现出它的威力了,我们可以通过 Pattern Match 充分玩转 Binary。

下面将以基因分离为例,讲解「变量层面的模式匹配」这个知识点。

**目标:**实现函数,将基因的二值部分与其余部分分离。

Elixir 实现:

@spec split_gene(binary) :: {binary, binary}
def split_gene(gene) do
  base2_size =
    gene
    |> byte_size()
    |> div(4)

  # 1/4 is base2
  <<binary_base2::bytes-size(base2_size), binary_base10::binary>> = gene
  {binary_base2, binary_base10}
end

只需一行代码,借助变量层面的模式匹配,我们便抽离出了binary_base2binary_base10

Rust:

Rust 中可借助nom这个库,以下是解析 hex color 为 RGB 的例子:

fn hex_color(input: &str) -> IResult<&str, Color> {
  let (input, _) = tag("#")(input)?;
  let (input, (red, green, blue)) = tuple((hex_primary, hex_primary, hex_primary))(input)?;

  Ok((input, Color { red, green, blue }))
}

Binary 的编码方式

常见地,「元」 Binary 可以被编码为 Base16、Base32、Base64 等多种形式。

image-20210802134357395

Binary 编码有助于让信息的传输更有效率,因此,Base64编码在我们的日常开发中非常常见。

和区块链相关的还有一种很重要的Binary 编码形式:Base58,Base58 的改进版 Base58Check 被用于比特币的地址生成中。

base58和base64一样是一种二进制转可视字符串的算法,主要用来转换大整数值。区别是,转换出来的字符串,去除了几个看起来会产生歧义的字符,如 0 (零), O (大写字母O), I (大写的字母i) and l (小写的字母L) ,和几个影响双击选择的字符,如/, +。

——https://www.jianshu.com/p/e002931bb38b

比特币之所以加入改进版的 Base58 算法,主要为了解决 Base58 导出的字符串没有校验机制,这样,在传播过程中,如果漏写了几个字符,会检测不出来。所以使用了改进版的算法 Base58Check。

实现是:在encode前,在输入流尾部加入输入内容的hash值(4个字节)。然后再对输入流进行 Base58Encode。

在 decode 时候:先 Base58Decode, 然后拆成两部分(内容和校验值),判断对内容计算的校验值和校验值字段是否一致。

比特币Base58相关源码地址: https://github.com/bitcoin/bitcoin/blob/master/src/base58.cpp

——https://www.jianshu.com/p/e002931bb38b

在 Rust 中,我们通过base**库来实现 Binary 的编码:

use base64::{encode, decode};
......

let result = encode(payload);

本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK