|
| 1 | +/* |
| 2 | + * This contract is used to verify customized sync_call entry function works. |
| 3 | + * It verifies customized sync_call entry is exported, and `call()` host function |
| 4 | + * can reach it. |
| 5 | + */ |
| 6 | + |
| 7 | +#include <eosio/eosio.hpp> |
| 8 | +#include <eosio/call.hpp> |
| 9 | + |
| 10 | +namespace eosio { |
| 11 | + |
| 12 | +class [[eosio::contract]] sync_call_cust_entry : public contract { |
| 13 | +public: |
| 14 | + using contract::contract; |
| 15 | + |
| 16 | + [[eosio::action]] |
| 17 | + void cusentrytst1() { |
| 18 | + // Make a sync call to "receiver"_n account, pass function ID in `data`, |
| 19 | + // go to `sync_call()` entry function, and dispatch the call to `get_10()` |
| 20 | + // based on the function ID. |
| 21 | + const std::vector<char> data{ eosio::pack(1) }; // function ID 1 |
| 22 | + eosio::call("receiver"_n, 0, data.data(), data.size()); |
| 23 | + |
| 24 | + // Retrieve return value and unpack it |
| 25 | + std::vector<char> return_value(sizeof(uint32_t)); |
| 26 | + eosio::get_call_return_value(return_value.data(), return_value.size()); |
| 27 | + |
| 28 | + // Verify it |
| 29 | + eosio::check(eosio::unpack<uint32_t>(return_value) == 10, "return value is not 10"); |
| 30 | + } |
| 31 | + |
| 32 | + [[eosio::action]] |
| 33 | + void cusentrytst2() { |
| 34 | + // Make a sync call to "receiver"_n account, pass function ID in `data`, |
| 35 | + // go to `sync_call()` entry function, and dispatch the call to `get_20()` |
| 36 | + // based on the function ID. |
| 37 | + const std::vector<char> data{ eosio::pack(2) }; // function ID 2 |
| 38 | + eosio::call("receiver"_n, 0, data.data(), data.size()); |
| 39 | + |
| 40 | + // Retrieve return value and unpack it |
| 41 | + std::vector<char> return_value(sizeof(uint32_t)); |
| 42 | + eosio::get_call_return_value(return_value.data(), return_value.size()); |
| 43 | + |
| 44 | + // Verify it |
| 45 | + eosio::check(eosio::unpack<uint32_t>(return_value) == 20, "return value is not 20"); |
| 46 | + } |
| 47 | + |
| 48 | + // `eosio::call` tag is optional |
| 49 | + uint32_t get_10() { |
| 50 | + return 10; |
| 51 | + } |
| 52 | + |
| 53 | + [[eosio::call]] |
| 54 | + uint32_t get_20() { |
| 55 | + return 20; |
| 56 | + } |
| 57 | +}; |
| 58 | +} /// namespace eosio |
| 59 | + |
| 60 | +extern "C" { |
| 61 | + [[eosio::wasm_entry]] |
| 62 | + int64_t sync_call(uint64_t sender, uint64_t receiver, uint32_t data_size) { |
| 63 | + eosio::datastream<const char*> ds(nullptr, 0); // for testing, not used |
| 64 | + eosio::sync_call_cust_entry obj(eosio::name{receiver}, eosio::name{receiver}, ds); |
| 65 | + |
| 66 | + std::vector<char> data(sizeof(uint32_t)); |
| 67 | + eosio::get_call_data(data.data(), data.size()); |
| 68 | + auto func_id = eosio::unpack<uint32_t>(data); |
| 69 | + |
| 70 | + // Dispatch sync calls |
| 71 | + uint32_t rv = 0; |
| 72 | + switch (func_id) { |
| 73 | + case 1: rv = obj.get_10(); break; |
| 74 | + case 2: rv = obj.get_20(); break; |
| 75 | + default: eosio::check(false, "wrong function ID"); |
| 76 | + } |
| 77 | + |
| 78 | + // set return value |
| 79 | + eosio::set_call_return_value(&rv, sizeof(uint32_t)); |
| 80 | + |
| 81 | + return 0; // return 0 to indicate success |
| 82 | + } |
| 83 | +} |
0 commit comments