1/* This file is part of DarkFi (https://dark.fi)
2 *
3 * Copyright (C) 2020-2025 Dyne.org foundation
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU Affero General Public License as
7 * published by the Free Software Foundation, either version 3 of the
8 * License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Affero General Public License for more details.
14 *
15 * You should have received a copy of the GNU Affero General Public License
16 * along with this program. If not, see <https://www.gnu.org/licenses/>.
17 */
1819use core::{mem::size_of, slice::from_raw_parts};
2021use crate::crypto::ContractId;
2223/// Success exit code for a contract
24pub const SUCCESS: i64 = 0;
2526#[macro_export]
27macro_rules! define_contract {
28 (
29 init: $init_func:ident,
30 exec: $exec_func:ident,
31 apply: $apply_func:ident,
32 metadata: $metadata_func:ident
33 ) => {
34/// # Safety
35#[no_mangle]
36pub unsafe extern "C" fn __initialize(input: *mut u8) -> i64 {
37let (contract_id, instruction_data) = $crate::wasm::entrypoint::deserialize(input);
3839match $init_func(contract_id, &instruction_data) {
40Ok(()) => $crate::wasm::entrypoint::SUCCESS,
41Err(e) => e.into(),
42 }
43 }
44#[no_mangle]
45pub unsafe extern "C" fn __entrypoint(input: *mut u8) -> i64 {
46let (contract_id, instruction_data) = $crate::wasm::entrypoint::deserialize(input);
4748match $exec_func(contract_id, &instruction_data) {
49Ok(()) => $crate::wasm::entrypoint::SUCCESS,
50Err(e) => e.into(),
51 }
52 }
53#[no_mangle]
54pub unsafe extern "C" fn __update(input: *mut u8) -> i64 {
55let (contract_id, update_data) = $crate::wasm::entrypoint::deserialize(input);
5657match $apply_func(contract_id, &update_data) {
58Ok(()) => $crate::wasm::entrypoint::SUCCESS,
59Err(e) => e.into(),
60 }
61 }
62#[no_mangle]
63pub unsafe extern "C" fn __metadata(input: *mut u8) -> i64 {
64let (contract_id, instruction_data) = $crate::wasm::entrypoint::deserialize(input);
6566match $metadata_func(contract_id, &instruction_data) {
67Ok(()) => $crate::wasm::entrypoint::SUCCESS,
68Err(e) => e.into(),
69 }
70 }
71 };
72}
7374/// Deserialize a given payload in `entrypoint`
75/// The return values from this are the input values for the above defined functions.
76/// # Safety
77pub unsafe fn deserialize<'a>(input: *mut u8) -> (ContractId, &'a [u8]) {
78let mut offset: usize = 0;
7980let contract_id_len = 32;
81let contract_id_slice = { from_raw_parts(input.add(offset), contract_id_len) };
82 offset += contract_id_len;
8384let instruction_data_len = *(input.add(offset) as *const u64) as usize;
85 offset += size_of::<u64>();
86let instruction_data = { from_raw_parts(input.add(offset), instruction_data_len) };
8788let contract_id = ContractId::from_bytes(contract_id_slice.try_into().unwrap());
89// We unwrap here because if this panics, something's wrong in the runtime:
90let contract_id = contract_id.unwrap();
9192 (contract_id, instruction_data)
93}