Skip to content

Instantly share code, notes, and snippets.

@t8
Created January 12, 2021 05:52
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save t8/e5485597c479b5c949aee580b7feeab2 to your computer and use it in GitHub Desktop.
Save t8/e5485597c479b5c949aee580b7feeab2 to your computer and use it in GitHub Desktop.
Test PST contract that supports the Foreign Call Protocol
export async function handle (state, action) {
const owner = state.owner;
const balances = state.balances;
const invocations = state.invocations;
const input = action.input;
const caller = action.caller;
if (input.function == "transfer") {
const target = input.target;
const qty = input.qty;
if (!Number.isInteger(qty)) {
throw new ContractError(`Invalid value for "qty". Must be an integer`);
}
if (!target) {
throw new ContractError(`No target specified`);
}
if (qty <= 0 || caller == target) {
throw new ContractError("Invalid token transfer");
}
if (balances[caller] < qty) {
throw new ContractError(`Caller balance not high enough to send ${qty} token(s)!`);
}
balances[caller] -= qty;
if (target in balances) {
balances[target] += qty;
} else {
balances[target] = qty;
}
return { state };
}
if (input.function == "balance") {
const target = input.target;
const ticker = state.ticker;
if (typeof target !== "string") {
throw new ContractError(`Must specificy target to get balance for`);
}
if (typeof balances[target] !== "number") {
throw new ContractError(`Cannnot get balance, target does not exist`);
}
return { result: { target, ticker, balance: balances[target] } };
}
if (input.function === "invoke") {
if (caller !== owner) {
throw new ContractError(`Caller does not own the token`);
}
if (!input.invocation) {
throw new ContractError(`Missing function invocation`);
}
state.foreignCalls.push(input.invocation);
return { state };
}
if (input.function === "foreignInvoke") {
if (!input.contract) {
throw new ContractError(`Missing contract to invoke`);
}
const foreignState = await SmartWeave.contracts.readContractState(input.contract);
if (!foreignState.foreignCalls) {
throw new ContractError(`Contract is missing support for foreign calls`);
}
const invocation = foreignState.foreignCalls[input.id];
if (invocations.includes(invocation)) {
throw new ContractError(`Contract invokation already exists`);
}
const foreignAction = action;
foreignAction.caller = input.contract;
foreignAction.input = invocation;
const resultState = handle(state, foreignAction);
return { resultState };
}
throw new ContractError(`No function supplied or function not recognised: "${input.function}"`);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment