HOWTOs

1. 怎么进行调试

默认情况下,合法的合约调用会在代理节点执行,但是普通节点也可以手动打开合约虚拟机,验证区块链中的合约调用,执行合约调用。

简单的调试方法可以通过pprint输出变量,对于基本类型pprint会输出多个参数值的字符串表示, 对于函数会输出函数的内存地址,对于table类型的值会转成json字符串输出。

之后会增加远程调试功能,在远程代理节点上运行过程中断点调试。

2. 怎么使用event

合约中可以通过emit EventName(EventArg)抛出,EventName是自定义event名称, event名称词法要求和变量名要求一样,但是最长支持49字符, EventArg是event的参数,要求值是最长1024字符的字符串

调用合约的操作执行过程中抛出的event,会被记录到区块链中,区块链本地节点可以设置监控某合约的某event的回调脚本, 然后在区块链同步到包含被监控的event的块时,会触发设置的脚本,回调脚本也是用uvm编写。

3. 常见编译错误有哪些

4. 对中文或者其他非英文的支持如何

变量名,函数名,event名称不可以使用中文,只能英文字符或者下划线开头,跟着若干个英文字符或者下划线或者数字, 但是字符串中的内容可以用中文或者其他语言的文字,支持unicode。

5. 支持多线程吗

因为uvm主要是为了在区块链的节点上运行的,考虑到区块链上的一些特性尤其是为了达成共识,不支持多线程编程

6. uvm中怎么使用随机数

提供两种获取随机数的方式

7. 怎么实现面向对象的类型继承和多态

可以使用table类型和record类型模拟对象,record类型有默认属性值,并且属性可以是有默认实现的函数

比如

type Person = {
    id: string default "123",
    name: string default "uvm",
    age ?: int = 24,  -- record属性默认值既可以用default也可以用=区分
    fn: (number, number) => number default 
            function (a: number, b: number) 
                return a + b
            end
}

let p = Person()
pprint(p.id, p.name, p.age)
let n = p.fn(p.age, 2016)
pprint(n)

如果需要实现类似面向对象语言中的类型继承和多态功能的话,可以实现一个extend函数,调用子record类型的构造函数后,用extend函数 接受子对象和父类型,在extend函数中创建新的父类型的对象,然后给把父类型对象中子类型对象没有的属性赋值给子类型对象。用这种 方法可以起到继承和多态的效果。目前没有给出标准的extend函数,给出一个示例实现

let function extend(obj, parent_class)
    let parent = parent_class(obj)
    for k, v in pairs(parent) do
        obj[k] = v
    return totable(obj)
end

type A = {
    name1: string,
    age1: int default 100
}

type B = {
    name: string,
    age: int
}

let b = B()
extend(b, A)

-- or

let c = extend(B(), A)

还有一种实现类型继承和多态的方法是使用setmetatable和元表,这以后会给出更多文档和例子