ROAST oracles for Ethereum smart contracts
ROAST (Robust Asynchronous Schnorr Threshold) signatures combine threshold cryptography with Schnorr signatures to enable secure, collaborative signing in decentralized and asynchronous settings. ROAST ensures robustness by tolerating network delays and malicious actors. It specifically safeguards honest participants’ ability to finalize signatures even in challenging network conditions, actively detecting and mitigating interference from malicious co-signers.
ROAST schema offers significant advantages for massive multi-signature setups and various forms of Multi-Party Computation (MPC), particularly suited to off-chain applications. In scenarios such as a large-scale multisig arrangement — for instance, 75 parties collaboratively controlling a Peercoin wallet with a threshold of 59 required signers — ROAST allows secure, scalable, and asynchronous cooperation. Any participant can propose a transaction, which is then reviewed and individually signed off-chain by group members. After collecting signatures from at least the threshold of participants, the transaction can be broadcasted to the blockchain by any member. An important benefit of ROAST in these massive multi-signature setups is privacy: despite the involvement of many signers, the resulting Peercoin address appears indistinguishable from a standard single-signer bech32 address on blockchain explorers, thus preserving confidentiality of the internal threshold setup.
This makes ROAST especially attractive for decentralized financial systems, secure custody solutions, governance voting schemes, and other complex scenarios where privacy, scalability, and resilience against asynchronous communication issues and malicious participants are crucial.
Imagine you’re part of an oracle network tasked with verifying outcomes of major sports events. When a game concludes, you’d open your mobile app, select the winning team, confirm your choice with a fingerprint signature, and submit your response. Once sufficient members of the oracle network agree on the result, the group collaboratively publishes cryptographic proof confirming their collective consensus. This exemplifies authentic peer-to-peer consensus, highlighting that the “peers” involved are real people working together seamlessly.
One could say that upcoming release (v1.4.0) of Peercoin Flutter wallet, which will enable users to form ROAST groups — is a wallet for workgroups indeed.

Distributed Oracles
An oracle in blockchain context is a trusted external entity responsible for providing real-world data or events onto the blockchain, enabling smart contracts or DLCs (Discreet Log Contracts) to execute according to external outcomes. Using ROAST threshold Schnorr signatures, this oracle function can be distributed across multiple independent participants, transforming a traditionally single-point-of-failure oracle into a robust workgroup. By distributing signing responsibility, ROAST oracles achieve internal accountability and resilience against individual dishonesty, errors, or malicious acts. With a ROAST-capable wallet installed directly on their phones, users can conveniently form human-to-human consensus workgroups, to collaboratively manage oracle tasks anytime and anywhere, effortlessly turning collective trust and verification into real-world blockchain inputs.
I have already explained in detail how will such distributed oracles work in context of DLCs on Peercoin blockchain, however in this article I want to explain how ROAST oracles are more universal and can be used on foreign blockchain networks like Ethereum (and myriad of its clones).
Ethereum (or any other EVM-based) blockchain does not natively support Schnorr signatures so it is not trivial to use a ROAST oracle with Ethereum. However, few years ago I stumbled upon this blog post which explains how to hack EVM and make it validate a Schnorr signature. Given that a ROAST signature is just a Schnorr signature — this means that this hack can be used to make the EVM validate a ROAST signature.
Similar methods are already employed by Chainlink, Witnet, Doot (Mina), Zero DAO and probably some others as well.
This example will focus on how implement a wrapped peercoin protocol for bridging peercoins to EVM-style blockchain. A threshold-wrapped peercoin token (tPPC).
“Lock-and-mint” cross-chain bridge
This method can connect Peercoin with Ethereum or allow for EVM-based sidechains running as companion chains to Peercoin. Let’s call any of these “chain E”.
The process is very straightforward conceptually: coins are locked on Peercoin, after which equivalent wrapped tokens are minted on the destination chain (E). When users wishes to reverse the process, they burn these wrapped tokens on Chain E — generating proof that allows unlocking of the coins on Peercoin.
However, there is a catch in this process: neither of chains cannot directly observe or verify events on the other. Simply put, blockchains are not aware of foreign blockchains.
To bridge this communication gap, a swarm of external witness nodes is formed. Witnesses observe both blockchains without directly interacting with neither. Upon reaching internal consensus on state of the blockchain — they issue cryptographically signed attestations verifying events like locking or burning of tokens. This attestation is delivered to the user off-chain. By employing a threshold cryptography approach, a large consortium of witnesses can collaboratively and securely validate events without any single trusted entity controlling the attestation process. In this case, consortium of witnesses is orchestrated by ROAST protocol.
Here is a snippet from example dart code, using coinlib, to produce a signed attestation.
// Oracle attestation to be signed
final attestation = Attestation(
chainId: 1,
amount: 1000000,
lockTransaction:
"f9a8b7c6d5e4f3a2b1c0d9e8f7a6b5c4d3e2f1a0b9c8d7e6f5a4b3c2d1e0f9a8",
);
print("Attestation: $attestation");
final attHash = attestation.encodeAndHash();
// Print hash in Solidity-compatible hex format
print("Attestation hash: 0x${bytesToHex(attHash)}");
final sig = SchnorrSignature.sign(key1.privateKey, attHash).data;
final signatureHex = "0x${bytesToHex(sig)}";
print("Signature: $signatureHex");
In practice, users deposit tokens into a contract on Peercoin, specifying details like the destination chain and address. Witness nodes observe this deposit and produce a signed attestation. The user then takes this attestation to the destination blockchain (Chain E), which verifies the attestation and mints the wrapped tokens accordingly.
Here is a solidity smart contract snippet, claimTokens function specifically - which yields the tokens on chain E.
/**
* @notice Claim tokens by providing a valid BIP340 signature from the oracle.
*/
function claimTokens(
uint32 _chainId,
uint64 _amount,
string calldata _lockTransaction,
string calldata _attType,
bytes calldata _signature
) external onlyEOA {
require(_chainId == block.chainid, "Wrong chainID");
// Expect 64 bytes total for BIP340: first 32 for rx, next 32 for s
require(_signature.length == 64, "Invalid signature length");
// Hash the parameters
// (chainId, amount, lockTx, attestation type)
bytes32 hashedMessage = keccak256(abi.encodePacked(_chainId, _amount, _lockTransaction, _attType));
// parse rx, s from signature
uint256 rx;
uint256 sigS;
assembly {
rx := mload(add(_signature, 32))
sigS := mload(add(_signature, 64))
}
// BIP340 signature verification
require(
Bip340Ecrec.verify(oraclePx, rx, sigS, hashedMessage),
"Invalid Oracle signature!"
);
// Ensure not replayed
require(!usedLockTransactions[_lockTransaction], "Already claimed!");
usedLockTransactions[_lockTransaction] = true;
// Mint tokens
_mint(msg.sender, _amount);
emit TokenMinted(msg.sender, _amount);
}
Full code example can be found here: