Is the following type of smart contract possible, and if so, what is it called?

  1. Party A creates a smart contract with available funds for a secondary party and signs the transaction
  2. Party B enters the correct the parameters to "unlock" the funds (parameters which are in no way related to Party A's private key) and signs the transaction

If I understand the goal, the trick is to work out the exchange of a secret, off-chain. It has to be off-chain or else everyone else will see it.

When someone arrives with knowledge of that secret, they can gain access to something. Here's a simple solution that handles many secrets and prizes in-flight. It might give you some ideas.

pragma solidity 0.6.6;

contract Secrets {
    mapping(bytes32 => uint) public secrets;
    function remit(bytes32 secret) public payable {
        secrets[secret] += msg.value;
    function claim(bytes32 magic) public {
        bytes32 secret = keyGen(msg.sender, magic);
        uint amount = secrets[secret];
        require(amount > 0, "There is no money for you.");
        secrets[secret] = 0;
    function keyGen(address a, bytes32 magic) public pure returns(bytes32 secret) {
        secret = keccak256(abi.encodePacked(a, magic));
  1. Sender makes a key with keyGen (off-chain, because it's pure).
  2. Sender uses the key to send money to the contract (on-chain).
  3. Sender gives the secret to the receiver, (somehow, off-chain, e.g. SMS)
  4. Receiver uses the key to get the money (on-chain).

Very simplified code to illustrate the point. Not production-ready. ;-)

Hope it helps.

  • Forgive my stupid question, but who pays for the unlocking of the funds? The creator or the receiver of them? Jun 26 '20 at 13:11
  • 1
    Unlocking will be paid by the receiver because the function is set up so only they can call it. Whoever sends the transaction pays the gas. Jun 26 '20 at 14:00


pragma solidity 0.4.26;

contract MyContract {
    address public partyB;

    constructor(address _partyB) public payable {
        partyB = _partyB;

    function withdraw() public {
        require(msg.sender == partyB);

I don't quite understand your goal though, since PartyA can simply transfer those funds directly to PartyB. In other words, why should PartyA be bothered with deploying a contract, and PartyB be bothered with calling a function on that contract?

  • I'm after something where Party X is not defined on construction of the contract. Where the funds are released to Party X if the inputs provided by Party X meet a certain condition. Party X could be anyone that is able to fulfil a condition unrelated to Party A's identity. Jun 25 '20 at 21:29
  • @wild_nothing: In the answer above, the condition is PartyB's private key, which is unrelated to PartyA's identity, exactly as you've stated in your question! Jun 25 '20 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.