Skip to content

Commit

Permalink
Example using a private key generated from the Suapp (#50)
Browse files Browse the repository at this point in the history
* Example using a private key generated from the Suapp

* Fix
  • Loading branch information
ferranbt committed Apr 2, 2024
1 parent e255f95 commit eaec84b
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 0 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,5 @@ run-integration:
go run examples/private-library/main.go
go run examples/private-library-confidential-store/main.go
go run examples/private-suapp-key/main.go
go run examples/private-suapp-key-gen/main.go
go run examples/std-transaction-signing/main.go
17 changes: 17 additions & 0 deletions examples/private-suapp-key-gen/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Example Suapp with a stored private key generated by the Suapp

This is a variation of the [private-suapp-key](../private-suapp-key) example. The difference is that the private key is generated by the Suapp itself during the `initialize` function.

## How to use

Run `Suave` in development mode:

```
$ suave --suave.dev
```

Execute the deployment script:

```
$ go run main.go
```
22 changes: 22 additions & 0 deletions examples/private-suapp-key-gen/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package main

import (
"log"

"github.com/flashbots/suapp-examples/framework"
)

func main() {
fr := framework.New()

contract := fr.Suave.DeployContract("private-suapp-key-gen.sol/PublicSuapp.json")

contract.SendConfidentialRequest("initialize", nil, nil)
receipt := contract.SendConfidentialRequest("example", nil, nil)

// validate the signature (TODO: return the address from the Suapp and validate the signature)
_, err := contract.Abi.Events["TxnSignature"].ParseLog(receipt.Logs[0])
if err != nil {
log.Fatal(err)
}
}
53 changes: 53 additions & 0 deletions examples/private-suapp-key-gen/private-suapp-key-gen.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.8;

import "suave-std/suavelib/Suave.sol";
import "suave-std/Context.sol";
import "suave-std/Suapp.sol";
import "suave-std/Transactions.sol";

contract PublicSuapp is Suapp {
Suave.DataId signingKeyBid;
string public KEY_PRIVATE_KEY = "KEY";

// onchain-offchain pattern to register the new private key in the Confidential storage
function updateKeyCallback(Suave.DataId _signingKeyBid) public {
signingKeyBid = _signingKeyBid;
}

function initialize() public returns (bytes memory) {
string memory keyData = Suave.privateKeyGen(Suave.CryptoSignature.SECP256);

address[] memory peekers = new address[](1);
peekers[0] = address(this);

Suave.DataRecord memory bid = Suave.newDataRecord(10, peekers, peekers, "private_key");
Suave.confidentialStore(bid.id, KEY_PRIVATE_KEY, abi.encodePacked(keyData));

return abi.encodeWithSelector(this.updateKeyCallback.selector, bid.id);
}

// offchain-onchain pattern to sign a transaction using the private key stored in the Suapp
event TxnSignature(bytes32 r, bytes32 s);

function exampleCallback() public emitOffchainLogs {}

function example() public returns (bytes memory) {
bytes memory signingKey = Suave.confidentialRetrieve(signingKeyBid, KEY_PRIVATE_KEY);

Transactions.EIP155Request memory txnWithToAddress = Transactions.EIP155Request({
to: address(0x00000000000000000000000000000000DeaDBeef),
gas: 1000000,
gasPrice: 500,
value: 1,
nonce: 1,
data: bytes(""),
chainId: 1337
});

Transactions.EIP155 memory txn = Transactions.signTxn(txnWithToAddress, string(signingKey));
emit TxnSignature(txn.r, txn.s);

return abi.encodeWithSelector(this.exampleCallback.selector);
}
}

0 comments on commit eaec84b

Please sign in to comment.