跳转至

require_recipient函数

函数在action.codon中的声明如下:

def require_recipient(account: Name):

require_recipient函数用来通知其它合约. 如果account合约有相同的action,那么这个action将被调用。

以下的sender.codon, receiver.codon的代码演示了如何从一个合约发送通知到另一个合约。

# sender.codon
from chain.name import Name
from chain.contract import Contract
from chain.action import require_recipient

@contract(main=True)
class MyContract(Contract):

    @action('sayhello')
    def sayhello(self, receiver: Name):
        print('hello, world')
        require_recipient(receiver)
# receiver.codon
from chain.name import Name
from chain.contract import Contract

@contract(main=True)
class MyContract(Contract):

    @action('sayhello', notify=True)
    def sayhello(self, receiver: Name):
        assert not self.receiver == self.first_receiver
        assert receiver == self.receiver
        print('hello, world from notify')

这里,要注意的是,receiver.codon中的sayhello函数和sender.codon中的sayhello函数的定义有些不同,receiver.codon中的sayhelloactiondecorator中多了notify=True,这是用来指定这个action是一个用来接收通知的action,只能通过调用require_recipient来触发。

以下是测试代码:

def init_notify():
    t = ChainTester(True)
    update_auth(t, 'hello')

    wasm_file = os.path.join(dir_name, 'notify/sender.wasm')
    with open(wasm_file, 'rb') as f:
        code = f.read()
    abi_file = os.path.join(dir_name, 'notify/sender.abi')
    with open(abi_file, 'r') as f:
        abi = f.read()
    t.deploy_contract('hello', code, abi)
    t.produce_block()

    wasm_file = os.path.join(dir_name, 'notify/receiver.wasm')
    with open(wasm_file, 'rb') as f:
        code = f.read()
    abi_file = os.path.join(dir_name, 'notify/receiver.abi')
    with open(abi_file, 'r') as f:
        abi = f.read()
    t.deploy_contract('alice', code, abi)
    t.produce_block()
    return t

def test_notify():
    t = init_notify()
    args = {'receiver': 'alice'}
    ret = t.push_action('hello', 'sayhello', args, {'hello': 'active'})
    t.produce_block()
    logger.info("++++++++++%s\n", ret['elapsed'])

编译:

python-contract build notify/receiver.codon
python-contract build notify/sender.codon

测试:

ipyeos -m pytest -s -x test.py -k test_notify

输出:

[(hello,sayhello)->hello]: CONSOLE OUTPUT BEGIN =====================
hello, world

[(hello,sayhello)->hello]: CONSOLE OUTPUT END   =====================
debug 2023-03-28T13:08:01.110 thread-0  apply_context.cpp:30          print_debug          ] 
[(hello,sayhello)->alice]: CONSOLE OUTPUT BEGIN =====================
hello, world from notify

[(hello,sayhello)->alice]: CONSOLE OUTPUT END   =====================