-
Notifications
You must be signed in to change notification settings - Fork 19
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add private library from confidential store
- Loading branch information
Showing
3 changed files
with
109 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
# Example Suapp with a Private library | ||
|
||
This example shows how Suapps can use private libraries stored in the confidential store that are not public in the Suave chain. | ||
|
||
The private code is saved in the confidential store with the `registerContract` function. The function receives the bytecode as confidential inputs such that the code is not leaked. Then, when the `example` function is called, it retrieves the library from the confidential stores and deploys it on-runtime. Note that this library is volatile and only visible as part of the confidential request, its bytecode and changes in the storage variables are never saved on-chain. | ||
|
||
## How to use | ||
|
||
Run `Suave` in development mode: | ||
|
||
``` | ||
$ suave --suave.dev | ||
``` | ||
|
||
Execute the deployment script: | ||
|
||
``` | ||
$ go run main.go | ||
``` |
61 changes: 61 additions & 0 deletions
61
examples/private-library-confidential-store/lib-confidential-store.sol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
pragma solidity ^0.8.8; | ||
|
||
import "../../suave-geth/suave/sol/libraries/Suave.sol"; | ||
|
||
contract PublicSuapp { | ||
event ContractRegistered ( | ||
Suave.BidId bidId | ||
); | ||
|
||
function registerContractCallback(Suave.BidId bidId) public payable { | ||
emit ContractRegistered(bidId); | ||
} | ||
|
||
function registerContract() public payable returns (bytes memory) { | ||
bytes memory bytecode = Suave.confidentialInputs(); | ||
|
||
address[] memory allowedList = new address[](1); | ||
allowedList[0] = address(this); | ||
|
||
Suave.Bid memory bid = Suave.newBid(0, allowedList, allowedList, "contract"); | ||
Suave.confidentialStore(bid.id, "bytecode", bytecode); | ||
|
||
return abi.encodeWithSelector(this.registerContractCallback.selector, bid.id); | ||
} | ||
|
||
function exampleCallback() public { | ||
} | ||
|
||
function example(Suave.BidId bidId) public payable returns (bytes memory) { | ||
bytes memory bytecode = Suave.confidentialRetrieve(bidId, "bytecode"); | ||
address addr = deploy(bytecode); | ||
|
||
PrivateLibraryI c = PrivateLibraryI(addr); | ||
uint256 result = c.add(1, 2); | ||
require(result == 3); | ||
|
||
return abi.encodeWithSelector(this.exampleCallback.selector); | ||
} | ||
|
||
function deploy(bytes memory _code) internal returns (address addr) { | ||
assembly { | ||
// create(v, p, n) | ||
// v = amount of ETH to send | ||
// p = pointer in memory to start of code | ||
// n = size of code | ||
addr := create(callvalue(), add(_code, 0x20), mload(_code)) | ||
} | ||
// return address 0 on error | ||
require(addr != address(0), "deploy failed"); | ||
} | ||
} | ||
|
||
interface PrivateLibraryI { | ||
function add(uint256 a, uint256 b) external pure returns (uint256); | ||
} | ||
|
||
contract PrivateLibrary { | ||
function add(uint256 a, uint256 b) public pure returns (uint256) { | ||
return a+b; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package main | ||
|
||
import ( | ||
"github.com/ethereum/go-ethereum/accounts/abi" | ||
"github.com/flashbots/suapp-examples/framework" | ||
) | ||
|
||
func main() { | ||
privateLibrary, _ := framework.ReadArtifact("lib-confidential-store.sol/PrivateLibrary.json") | ||
|
||
fr := framework.New() | ||
suapp := fr.DeployContract("lib-confidential-store.sol/PublicSuapp.json") | ||
|
||
// Deploy the contract and get the bid id | ||
receipt := suapp.SendTransaction("registerContract", nil, privateLibrary.Code) | ||
event, _ := contractRegisteredABI.Inputs.Unpack(receipt.Logs[0].Data) | ||
privateContractBidId := event[0].([16]byte) | ||
|
||
// Use the private contract | ||
suapp.SendTransaction("example", []interface{}{privateContractBidId}, nil) | ||
} | ||
|
||
var contractRegisteredABI abi.Event | ||
|
||
func init() { | ||
artifact, _ := framework.ReadArtifact("lib-confidential-store.sol/PublicSuapp.json") | ||
contractRegisteredABI = artifact.Abi.Events["ContractRegistered"] | ||
} |