2021.5.4

Motoko笔记

Motoko的共享函数支持一种简单的调用方标识形式,允许您检查与函数调用方关联的IC(Internet Computer)主体。与调用关联的主体是标识唯一用户或容器(canister)的值。

可以使用与函数调用方关联的主体在程序中实现基本形式的访问控制。

在Motoko中,shared关键字用于声明共享函数。共享函数还可以携带{caller:Principal}类型的可选参数。

要说明如何访问共享函数的调用者,请考虑以下内容:

shared(msg) func inc() : async () { 
// ... msg.caller ... 
}

结果:func : shared () -> async ()

在本例中,共享函数inc()指定一个msg参数、一条记录,msg.caller访问msg的principal字段。

对inc()函数的调用不会改变-在每个调用站点,调用方的principal由系统提供,而不是由用户提供,因此principal不能被恶意用户伪造或欺骗。

要访问actor类构造函数的调用方,可以对actor类声明使用相同的(可选)语法。例如:

shared(msg) actor class Counter(init : Nat) { 
// ... msg.caller ... 
}

为了扩展这个例子,假设您想要限制Counter actor,以便它只能由Counter的安装程序修改。为此,可以通过将actor绑定到一个owner变量来记录安装actor的principal。然后可以检查每个方法的调用方是否等于owner,如下所示:

shared(msg) actor class Counter(init : Nat) {
	let owner = msg.caller; 
	var count = init; 
	public shared(msg) func inc() : async () { 
		assert (owner == msg.caller); 
		count += 1; 
	}; 
	public func read() : async Nat { count }; 
	public shared(msg) func bump() : async Nat { 
		assert (owner == msg.caller); 
		count := 1; 
		count; 
	}; 
}

在本例中,如果调用未经授权,assert(owner==msg.caller)表达式会导致函数inc()和bump()陷入陷阱,从而防止修改count变量,而任何调用方都被允许使用read()函数。

shared的参数只是一个模式,因此,如果您愿意,还可以重写上面的内容以使用模式匹配:

shared({caller = owner}) actor class Counter(init : Nat) { 
	var count : Nat = init; 
	public shared({caller}) func inc() : async () { 
		assert (owner == caller); 
		count += 1; 
	}; 
	// ... 
}

Principal支持相等、排序和散列(support equality, ordering, and hashing),因此可以有效地将Principal存储在容器中,例如,维护允许或拒绝列表。有关Principal的更多操作,请参阅 Principal base library。


A Student on the way to full stack of Web3.