Skip to main content

Shielded and Unshielded Token Transfers

This Compact contract implements send, receive and mint functions for tokens in Compact. It offers demonstration of the following features:

  • Minting and receiving unshielded tokens to the contract
  • Sending unshielded tokens to a user
  • Receiving unshielded tokens
  • Night token operations
  • Shielded token operations
import CompactStandardLibrary;


// Mint using mintUnshieldedToken() + receiveUnshielded()
export circuit mintAndReceive(amount: Uint<64>): Bytes<32> {
const domain = pad(32, "simple:receive");

const color = mintUnshieldedToken(
disclose(domain),
disclose(amount),
left<ContractAddress, UserAddress>(kernel.self())
);

return color;
}


// Send to user address
export circuit sendToUser(amount: Uint<64>, user_addr: UserAddress): [] {
const domain = pad(32, "simple:receive");
const color = tokenType(disclose(domain), kernel.self());

sendUnshielded(
color,
disclose(amount) as Uint<128>,
right<ContractAddress, UserAddress>(disclose(user_addr))
);
}

export circuit receiveTokens(amount: Uint<128>): [] {
const domain = pad(32, "simple:receive");
const color = tokenType(domain, kernel.self());
receiveUnshielded(color, disclose(amount));
}

export circuit receiveNightTokens(amount: Uint<128>): [] {
receiveUnshielded(default<Bytes<32>>, disclose(amount));
}

export circuit sendNightTokensToUser(amount: Uint<64>, user_addr: UserAddress): [] {
sendUnshielded(
default<Bytes<32>>,
disclose(amount) as Uint<128>,
right<ContractAddress, UserAddress>(disclose(user_addr))
);
}

export circuit receiveShieldedTokens(coin: ShieldedCoinInfo): [] {
receiveShielded(disclose(coin));
}

export circuit sendShieldedToUser(input: QualifiedShieldedCoinInfo, publicKey: ZswapCoinPublicKey, value: Uint<128>): ShieldedSendResult {
return sendShielded(disclose(input), left<ZswapCoinPublicKey, ContractAddress>(disclose(publicKey)), disclose(value));
}

export circuit mintShieldedToSelf(domainSep: Bytes<32>, value: Uint<64>, nonce: Bytes<32>): ShieldedCoinInfo {
return mintShieldedToken(disclose(domainSep), disclose(value), disclose(nonce), right<ZswapCoinPublicKey, ContractAddress>(kernel.self()));
}

export circuit mintAndSendShielded(domainSep: Bytes<32>, mintValue: Uint<64>, mintNonce: Bytes<32>, publicKey: ZswapCoinPublicKey, sendValue: Uint<128>): ShieldedSendResult {
const coin = mintShieldedToken(disclose(domainSep), disclose(mintValue), disclose(mintNonce), right<ZswapCoinPublicKey, ContractAddress>(kernel.self()));
const qualified = QualifiedShieldedCoinInfo { nonce: coin.nonce, color: coin.color, value: coin.value, mt_index: 0 as Uint<64> };
return sendShielded(qualified, left<ZswapCoinPublicKey, ContractAddress>(disclose(publicKey)), disclose(sendValue));
}