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));
}