diff --git a/docs/builder-solidity.mdx b/docs/builder-solidity.mdx deleted file mode 100644 index 919b5865..00000000 --- a/docs/builder-solidity.mdx +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: Builder Solidity -description: Do more with solidity on SUAVE -keywords: - - key - - concepts - - suave - - builder - - solidity ---- - -## Verifiable logic, private data - -Block builders currently have no incentive to share the algorithms by which they build blocks, and searchers depend on builders to ensure their bundles are included. This trust-dependency results in block builder centralization, irrespective of architecture or consensus mechanism. - -Builder solidity enables anyone to create contracts that specify exactly how they will order sensitive data sent to them. There are many potential incentives for creating such contracts in the open: - -1. The credible neutrality of an open marketplace in which many parties share their views, strategies, and opinions gives SUAVE an information advantage on centralized builders. -2. There are efficiency gains when aggregating and clearing user preferences inside the same auction. More users means more orderflow means more likelihood of landing blocks, or settling auctions, successfully. -3. Block builders who only operate on a single domain will find themselves increasingly disadvantaged due to cross-domain MEV. Builder solidity on SUAVE should decrease the cost (and complexity) of building blocks for many different blockchains. -4. Enabling computation on sensitive data in a permissionless setting is hard. By solving it once, builder solidity contracts amortize the cost across the ecosystem and provide better solutions more cheaply than any individual participant could. - -## Open to All - -Builder solidity is not just for block builders, though. - -Builder solidity contracts are a _uniform programming model for implementing every component of the [transaction supply network](https://frontier.tech/infinite-games)_, such that we can ensure that any value created is distributed well. An auction for blockspace is not very different from an auction for solving user preferences. We expect that mechanisms which work well for either will translate into many different use cases. - -The result should be continuous improvement of mechanisms which compete for sensitive data, and do so by virtue of the efficiency of their implementation _combined with_ the guarantees their contracts make about how they will distribute value arising from the aggregation of such data. - -Our intention is to create a viable environment for **keeping power decentralized**. - -## Builder Solidity - -Builder solidity looks something like this [[🔗 source](https://github.com/flashbots/suave-geth/blob/main/suave/sol/standard_peekers/bids.sol)]: - -```solidity -pragma solidity ^0.8.8; - -import "../libraries/Suave.sol"; - -contract AnyBundleContract { - - event DataRecordEvent( - Suave.DataId dataId, - uint64 decryptionCondition, - address[] allowedPeekers - ); - - function fetchConfidentialBundleData() public returns (bytes memory) { - require(Suave.isConfidential()); - - bytes memory confidentialInputs = Suave.confidentialInputs(); - return abi.decode(confidentialInputs, (bytes)); - } - - function emitDataRecord(Suave.DataRecord calldata dataRecord) public { - emit DataRecordEvent(dataRecord.id, dataRecord.decryptionCondition, dataRecord.allowedPeekers); - } -} -``` - -Builder solidity contracts are used to define the public logic that is used for confidential computation. Using a precompile like `confidentialInputs` allows [SUAVE Kettles](/technical/specs/rigil/kettle) to access encrypted data from users, do stuff with it privately and only reveal the results, not the inputs. - -This ensures confidentiality **and** improves efficiency, enabling computation that is not possible on blockchains like Ethereum. - -## Confidential Computation - -**TODO:** - -1. Explain view functions and how we use those for execution of `confidentialComputeRequests` -2. An example of a very simple request and response object on a view function to show how it all works with data points -3. A more in-depth data flow - -## Further context - -We recommend [this early research talk from Andrew Miller](https://youtu.be/DhsDFKnHPa0?t=344) to get a sense of the ideas from which builder solidity has grown. - -Please note that the pseudo code Andrew shows is now outdated and you are better off learning from our [how to create contracts guide](/tutorials/deploy-contracts/) above, or looking directly at our [list of available precompiles](/technical/specs/rigil/precompiles). That said, the framework used in this talk and the background provided should still prove useful when writing your own builder solidity contracts. diff --git a/docs/cheatsheet.mdx b/docs/cheatsheet.mdx deleted file mode 100644 index 5c28b904..00000000 --- a/docs/cheatsheet.mdx +++ /dev/null @@ -1,473 +0,0 @@ ---- -title: Docs Cheatsheet ---- - -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -import TOCInline from '@theme/TOCInline'; - -On this page you'll find every single markdown & mdx component used in our docs - -## Page Title & Data - -For the title of the page, and the name of the tab, at the very top of your file, just add this code snippet to the top. - -Any thing between the `---` tags will be used for the meta data of the page - -```md ---- -title: Cheatsheet -id: page-id-when-linking-to-it ---- -``` - -For Heading 1 specifically, you should set the page title in the meta data. - -[Docusaurus source docs](https://docusaurus.io/docs/next/markdown-features/headings) - -```md -# Heading 1 -``` - -## Heading 2 - -```md -## Heading 2 -``` - -### Heading 3 - -```md -### Heading 3 -``` - -#### Heading 4 - -```md -#### Heading 4 -``` - -##### Heading 5 - -```md -##### Heading 5 -``` - -###### Heading 6 - -```md -###### Heading 6 -``` - -## Line breaks - -```md -Some text - -With a line between them -``` - -## Lists - -### Unordered lists - -- Unordered list 1 -- Unordered list 2 -- Unordered list 3 - -```md -- Unordered list 1 -- Unordered list 2 -- Unordered list 3 -``` - -### Unordered lists - -You don't actually have to do the numbers, as long as there is a number at the start it'll count incrementally starting with the first number in the list - -1. Ordered list 1 -2. Ordered list 2 -3. Ordered list 3 - -```md -1. Ordered list 1 -2. Ordered list 2 -3. Ordered list 3 -``` - -### Nested & Mixed lists - -1. Ordered list - 1. Sable - 2. Ferret - - Cat rat - - Fox weasel - 3. Lamp -2. Ordered list - - Grape - - Potatoes - - Chips - 1. Crisps - 1. Fondant - 1. Frites - - Lemons - 1. Three cats - 1. Pasta - 1. Ragu -3. Ordered list - -```md -1. Ordered list - 1. Sable - 2. Ferret - - Cat rat - - Fox weasel - 3. Lamp -2. Ordered list - - Grape - - Potatoes - - Chips - 1. Crisps - 1. Fondant - 1. Frites - - Lemons - 1. Three cats - 1. Pasta - 1. Ragu -3. Ordered list -``` - -## Text styling - -_Italic/Emphasize_ - -```md -_Italic/Emphasize_ -``` - -**Strong/Bold** - -```md -**Strong/Bold** -``` - -**_Italic & Bold_** - -```md -**_Italic & Bold_** -``` - -## Codeblocks - -So you basically define a section using the ` ``` ` anything between two lines that contain these 3 back quotes will be in the block - -If you want specific formatting for a certain language like for example Javascript here: - -```js -const threeCats = ['cat', 'cat', 'cat']; -``` - -```md -Mind the indentation here, code blocks in code blocks isn't normal usage `js const threeCats = ["cat", "cat", "cat"] ` -``` - -Theres a lot of different formattings to use, `md`, `js`, `ts`, etc. The package used is [Prism react render](https://github.com/FormidableLabs/prism-react-renderer) - -## Quotes - -> Quoted text. - -> > Quoted quote. - -> Quoted text. -> -> > Quoted quote. -> > -> > > Quoted quote. - -> Quoted text. -> -> > Quoted quote. -> > -> > > Quoted quote. -> > > -> > > > Quoted quote. - -```md -> Quoted text. - -> > Quoted quote. - -> Quoted text. -> -> > Quoted quote. -> > -> > > Quoted quote. - -> Quoted text. -> -> > Quoted quote. -> > -> > > Quoted quote. -> > > -> > > > Quoted quote. -``` - -## Admonitions - -These are nifty notification blocks [from Docusaurus](https://docusaurus.io/docs/next/markdown-features/admonitions) - -:::note - -The content and title _can_ include markdown. - -::: - -:::note Your Title - -The content and title _can_ include markdown. - -::: - -:::tip You can specify an optional title - -Heads up! Here's a pro-tip. - -::: - -:::info - -Useful information. - -::: - -:::caution - -Warning! You better pay attention! - -::: - -:::danger - -Danger danger, mayday! - -::: - -``` -:::note - -The content and title *can* include markdown. - -::: - -:::note Your Title - -The content and title *can* include markdown. - -::: - -:::tip You can specify an optional title - -Heads up! Here's a pro-tip. - -::: - -:::info - -Useful information. - -::: - -:::caution - -Warning! You better pay attention! - -::: - -:::danger - -Danger danger, mayday! - -::: -``` - -## Links - -The links in this paragraph are being pulled from a list [a link][1] and another [link][2]. - -```md -The links in this paragraph are being pulled from a list [a link][1] and another [link][2]. -``` - -```md -This is that list - -[1]: http://example.com/ 'Title' -[2]: http://example.org/ 'Title' -``` - -[1]: http://example.com/ 'Title' -[2]: http://example.org/ 'Title' - -## Images - -### Alt tags for images - -You can update the alt tag data for text like this: - -Logo: ![Alt](/img/logo.png 'Flashbots logo') - -```md -Logo: ![Alt](/img/logo.png 'Flashbots logo') -``` - -You can create a image with a hyperlink to another page or a hash link on the page by adding the link in the brackets next to it - -Linked logo: [![alt text](//img/logo.png)](https://docs.flashbots.net/ 'Off to the docs') - -```md -Linked logo: [![alt text](//img/logo.png)](https://docs.flashbots.net/ 'Off to the docs') -``` - -## MDX features - -A quick note on using what's called `.mdx` features, `mdx` means markdown extended, to used these features, you need to name your file to have the extension `.mdx` - -For example `cheatsheet.mdx` - -This lets you use react components that are a bit more intricate that the standard markdown features. - -To make use of an `mdx` component like `Tabs`, you need to add any `import ... from ...` lines to the top of the page, but below the meta data section. Heres an example: - -``` ---- -title: Cheatsheet (Heading 1) ---- -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; -``` - -### Tabs - -This is an example of the `tabs` component. - -For extend usage, please refer to the [Docusaurus documentation.](https://docusaurus.io/docs/next/markdown-features/tabs) - - - This is an apple 🍎 - This is an orange 🍊 - This is a banana 🍌 - - -```mdx -import Tabs from '@theme/Tabs'; -import TabItem from '@theme/TabItem'; - - - This is an apple 🍎 - This is an orange 🍊 - This is a banana 🍌 - -``` - -### Inline Table of Contents - -If you need a table contents literally anywhere, you can make use of the `` component. - -For extend usage, please refer to the [Docusaurus documentation.](https://docusaurus.io/docs/next/markdown-features/inline-toc) - - - -```mdx -import TOCInline from '@theme/TOCInline'; - - -``` - -## Footnotes & references - -This is how we make a reference to a foot note or reference that's found at the bottoms of the page.[^1] - -```md -This is how we make a reference to a footnote [^1] that's found at the bottoms of the page -``` - -To create list of foot notes, you just add list like this somewhere, preferably at the bottom of the file - -```md -[^1]: an amazing foot note, you can add links n things here as usual -``` - -## Docusaurus-specific considerations - -There's a couple things to be aware of when adding your own `*.md` files to our codebase: - -- Please remove all `HTML` elements -- Links are done using `[text](link)` this can link out to external links or to local docs files -- For images, use the syntax `![Alt Text](image url)` to add an image, alternatively see below: - -```md -Example banner -``` - -### Adding meta data to your doc - -The docs make use of a feature called [frontmatter](https://docusaurus.io/docs/api/plugins/@docusaurus/plugin-content-docs#markdown-frontmatter) which lets you add some meta data and control the way the docs are referenced through the site. - -This is done by adding a small section to the top of your doc like this: - -```md ---- -title: Example Doc ---- -``` - -That title in the example will automatically add a `# Heading` to your page when it renders - -There are a couple settings available; - -Such as specifying the url you would like using - -`slug: /questionably/deep/url/for/no/reason/buckwheat-crepes` - -Adding `keywords` or `description` etc, below is a full example: - -``` ---- -id: not-three-cats -title: Three Cats -hide_title: false -hide_table_of_contents: false -sidebar_label: Still not three cats -custom_edit_url: https://github.com/flashbots/docs/edit/main/docs/three-cats.md -description: Three cats are not unlike four cats like three cats -keywords: - - cats - - three -image: ./assets/img/logo.png -slug: /myDoc ---- -My Document Markdown content -``` - -### Side bar navigation - -To update the high level navigation, open the file in `docs/sidebars.js` and arrange n order as required. The titles for links are pulled from their files. - -The `items` here take a page ID, a page ID by default is the title of the file, as example `example-doc.md` would be `example-doc` - -To read the Docusaurus docs, [click here](https://docusaurus.io/docs/sidebar) - -[^1]: an amazing foot note, you can add links n things here as usual diff --git a/docs/concepts/block-building.mdx b/docs/concepts/block-building.mdx new file mode 100644 index 00000000..eec1beff --- /dev/null +++ b/docs/concepts/block-building.mdx @@ -0,0 +1,75 @@ +--- +title: Block Building +description: How you can use SUAVE to build blocks on other chains +--- + +# Block Building + +One of the unique features that SUAVE enables is block construction for other chains. Whether you're working on constructing transactions, creating bundles, or building blocks, this feature gives you the capability to interact with the latest blockchain state. + +## Practical Example + +Here is an example of a smart contract that demonstrates the practical application of a block building session: + +```solidity +function sessionExample(bytes memory subTxn, bytes memory subTxn2) public payable returns (bytes memory) { + string memory id = Suave.newBuilder(); + + Suave.SimulateTransactionResult memory sim1 = Suave.simulateTransaction(id, subTxn); + require(sim1.success == true); + require(sim1.logs.length == 1); + + // Simulate the same transaction again should fail due to nonce repetition + Suave.SimulateTransactionResult memory sim2 = Suave.simulateTransaction(id, subTxn); + require(sim2.success == false); + + // Simulate the transaction with the correct nonce + Suave.SimulateTransactionResult memory sim3 = Suave.simulateTransaction(id, subTxn2); + require(sim3.success == true); + require(sim3.logs.length == 2); + + return abi.encodeWithSelector(this.emptyCallback.selector); +} +``` + +In this example, a new builder session is created, and multiple transactions are simulated with varying conditions in order to illustrate how you might approach building blocks with SUAVE. + +## Conceptual Explanation + +SUAVE exposes several precompiles to help you with transaction simulation and block construction. + +If your SUAPP is intended to produce blocks, be they partial or full, you'll first need to start a new builder session. The precompile this calls in the [`suave-std` library](https://github.com/flashbots/suave-std/blob/main/src/suavelib/Suave.sol) looks like this: + +```solidity +function newBuilder() internal view returns (string memory) +``` + +This function starts a new builder instance within a Kettle. The basic idea is that session ids (the `string` returned by the `newBuilder()` precompile) provide programmatic control when building blocks, one outcome of which is simulating transactions more efficiently. Opening a session enables you to build block iteratively, rather than having to re-run all your simulations each time you receive a new transaction or bundle. + +:::info + +If you'd prefer to just read how the builder is implemented in `suave-geth`, you can [**do so here**](https://github.com/flashbots/suave-geth/blob/main/suave/builder/builder.go). + +::: + +Once you receive transactions or bundles, it is often the case that you need to simulate the effect they will have on the state of the target chain for which your SUAPP is building blocks. You'll often want to construct blocks in stages, as your SUAPP receive various different bundles and/or transactions from different users. This can be achieved with either of the below precompiles: + +```solidity +function simulateBundle(bytes memory bundleData) internal view returns (uint64) +function simulateTransaction(string memory sessionid, bytes memory txn) internal view returns (SimulateTransactionResult memory) +``` + +If you're happy with the results of your simulation and wish to build a block based on the bundles/transactions you've received, you can use one more precompile: + +```solidity +function buildEthBlock(BuildBlockArgs memory blockArgs, DataId dataId, string memory namespace) internal view returns (bytes memory, bytes memory) +``` + +As the name suggests, we only support building blocks on Ethereum L1 for now. This will change as SUAVE matures. + +All of these functions utilize the SUAVE Execution Namespace. To understand more about this, please consult the [Execution Namespace specification](/technical/specs/rigil/mevm.md#suavex-namespace). + +## Bundles + +Bundles are one or more transactions that are grouped together and executed in the order they are provided and are the core unit of block building. If you're unfamiliar with bundles, and want to learn more, you can read [this document](https://docs.flashbots.net/flashbots-auction/advanced/understanding-bundles). + diff --git a/docs/concepts/confidential-computation.mdx b/docs/concepts/confidential-computation.mdx new file mode 100644 index 00000000..c04c3d25 --- /dev/null +++ b/docs/concepts/confidential-computation.mdx @@ -0,0 +1,64 @@ +--- +title: Confidential Computation +description: How to understand confidential computation on SUAVE and use it to yur advantage. +--- + +import List from '@site/src/components/List/List.tsx'; + +Confidential computation enables you to handle orderflow privately and securely. + +In SUAVE, we achieve this with [Kettles](/technical/specs/rigil/kettle#confidential-computation) performing compute offchain, but according to smart contracts written onchain. In this way, offchain compute is not constrained by chain consensus. The Kettles will eventually run in [TEEs](https://www.youtube.com/watch?v=ek-bu4aoh0A), which provide both enhanced privacy (no-one, not even the host OS, can see unencrypted data) and integrity (you can be sure the correct code, and only that code, is running at all times). + +## How It Works + +:::info + +For practical examples of how Confidential Compute Requests (CCRs) work, please follow [**this tutorial**](/tutorials/confidential-compute-requests). The below will explain CCRs conceptually, without code. + +::: + + + +**Starting Point**: A user sends "Confidential Compute Request" using `eth_sendRawTransaction`, which is received by the JSON RPC. + +
+ +**MEVM Execution**: Upon receiving the request, the JSON RPC triggers the MEVM (Modified Ethereum Virtual Machine) to run. MEVM execution can use multiple APIs depending on the context, with two possible paths: + + + +**Request to an External Domain**: The MEVM can make API requests to external domains: i.e. if you're running an Ethereum node, it can fetch state from there for simulations etc., or if the SUAPP uses the `doHttpRequest()` precompile, it can fetch arbitrary information required for the offchain compute. + +**Request to the Confidential Datastore**: The MEVM can make API requests directly to the "Confidential Datastore" to fetch or store data. + + + +
+ +**Broadcast results**: Eventually, after processing the request the MEVM can take the results and, depending on the SUAPP's logic, send a SUAVE transaction, which is a transaction object that contains the result of the CCR in its calldata (and the signature of the Kettle which computed said result), which enables other users or contracts to take action. + +**Transaction Hash Output**: A transaction hash for the Suave transaction above is produced and returned to the request's originator, just like Ethereum. + +
+ +### Computing over Confidential Data + +How to index, store, and use confidential data is left up to each SUAPP. + +For example, in the [Private OFA Suapp](https://github.com/flashbots/suapp-examples/tree/main/examples/app-ofa-private), to submit a valid backrun, a searcher must include the `recordId` of the user transaction in order for the Suapp to match them. Therefore, the Suapp emits the user transaction `recordId` as a log on chain, which searchers can listen for and use to construct valid backruns. + +However, the NFTEE example demonstrates how to store a private key in the confidential store. In order to get it to sign a transaction intended for Ethereum L1, we store the `recordId` associated with that private key in the contract's memory, which ends up onchain. In this context, this is not a concern, since it's gated, so only that Suapp can access the key for signing purposes. + +### Restricting Access + +You need not use confidential requests in the ways which our examples illustrate. For instance, if you wish to restrict access to methods with a modifier requiring some confidential secret, you can do so. This can be achieved by following the below steps, contributed by Miha: + +1. When you initialize a contract, pass it a secret key which is stored in confidential storage. +2. Use this key with the local nonce to derive the next secret. +3. The hash of the present secret is in public (evm) storage. +4. Whenever a restricted method is accessed, the present secret needs to be provided. + 1. This is only accessible through confidential execution. + +You can find Miha's implementation of [ConfidentialControl here](https://github.com/halo3mic/suave-playground/blob/9afe269ab2da983ca7314b68fcad00134712f4c0/contracts/blockad/lib/ConfidentialControl.sol), along with a [good example which illustrates its use](https://github.com/halo3mic/suave-playground/blob/9afe269ab2da983ca7314b68fcad00134712f4c0/contracts/blockad/BlockAdV2.sol). + +This particular approach, and the reason it currently works in this manner, is being discussed in this [`suave-geth` issue](https://github.com/flashbots/suave-geth/issues/121). \ No newline at end of file diff --git a/docs/concepts/confidential-data-storage.mdx b/docs/concepts/confidential-data-storage.mdx new file mode 100644 index 00000000..902a97d3 --- /dev/null +++ b/docs/concepts/confidential-data-storage.mdx @@ -0,0 +1,90 @@ +--- +title: Confidential Data Storage +description: How to leverage confidential data to your advantage when building on SUAVE +--- + +import List from '@site/src/components/List/List.tsx'; + +## Data Records + +Confidential storage works with opaque identifiers, which are generated by Kettles when data is put in storage during offchain/confidential computation. These identifiers are part of an object we call a `DataRecord`, which holds a reference to the data, its ID, who can store and retrieve it, and a few other pieces of metadata. + +This is what these DataRecords look like in the [`suave-std` library](https://github.com/flashbots/suave-std/blob/main/src/suavelib/Suave.sol): + +```solidity + type DataId is bytes16; + + struct DataRecord { + DataId id; + DataId salt; + uint64 decryptionCondition; + address[] allowedPeekers; + address[] allowedStores; + string version; + } +``` + +## Practical Example + +Consider the same [Private OFA Suapp](https://github.com/flashbots/suapp-examples/blob/main/examples/app-ofa-private/ofa-private.sol) from the previous tutorial. The OFA contract needs to accept user transactions, store them, and emit a hint that searchers can use. It then needs to accept backruns from searchers and match those with the user transactions in storage: a task it achieves by means of the `recordId`. + +The end-to-end flow looks like this: + + + +A user submits a transaction they wish to be included in the orderflow auction, calling the `newOrder()` function. + +
+ +The contract defines logic which a Kettle can use to get the confidential data, simulate the results of including this transaction, and extract the hint to be shared with searchers. + +```solidity +bytes memory bundleData = Suave.confidentialInputs(); +uint64 egp = Suave.simulateBundle(bundleData); +bytes memory hint = Suave.extractHint(bundleData); +``` +
+ +
+ +The contract then sets who can store and "peek" (i.e. retrieve) the data. In this case, both this Private OFA contract and the precompile contract deployed at the address `0x...43200001` are set as **allowedPeekers** and **allowedStores** (though you could have totally different addresses in these arrays in your own use case). If you consult the [`suave-std` library](https://github.com/flashbots/suave-std/blob/main/src/suavelib/Suave.sol), you'll see that the precompile deployed at that address is the `FILL_MEV_SHARE_BUNDLE`, which is what we require for this particular contract. + +```solidity +address[] memory allowedList = new address[](2); +allowedList[0] = address(this); +allowedList[1] = 0x0000000000000000000000000000000043200001; +``` + +
+ +
+ +Then, we create the `dataRecord`. The `decryptionCondition` is passed in as an argument and can be anything (though `decryptionConditions` will be deprecated soon) and the version is left as a blank string. Then, we write both the transaction itself, and the results from its simulation (in this case, the effective gas price after it is included) into the confidential store at different keys, which we will later use to match bundles and backruns in order to build profitable blocks. + +```solidity +Suave.DataRecord memory dataRecord = Suave.newDataRecord(decryptionCondition, allowedList, allowedList, ""); +Suave.confidentialStore(dataRecord.id, "mevshare:v0:ethBundles", bundleData); +Suave.confidentialStore(dataRecord.id, "mevshare:v0:ethBundleSimResults", abi.encode(egp)); +``` + +
+ +
+ +The hint is not directly emitted on chain, as Confidential Compute Requests cannot directly change state, but rather is emitted as a callback once the order has been saved and the hint returned: + +```solidity +return abi.encodeWithSelector(this.emitHint.selector, hintOrder); +``` + +
+ +Searchers can then use the information in this event to construct and submit valid backruns, which are matched against the original transactions via the `hintId`. + +Matched transactions and backruns are bundled together via the `fillMevShareBundle()` precompile. + +These bundles are sent to predefined off chain builders via the `submitBundleJsonRPC()` precompile. + +
+ +In this manner, the Confidential Data Store enables you to create applications on chain that can provide features credible pre-trade privacy (and more!) while nevertheless exposing their business logic in a verifiable and contestable manner. \ No newline at end of file diff --git a/docs/concepts/index.mdx b/docs/concepts/index.mdx new file mode 100644 index 00000000..23527758 --- /dev/null +++ b/docs/concepts/index.mdx @@ -0,0 +1,36 @@ +--- +title: How SUAVE Extends Solidity +description: Understand more about SUAVE +keywords: + - explanations + - suave + - concepts +--- + +import List from '@site/src/components/List/List.tsx'; + +SUAVE gives you, an application developer, a way to: + + + +Define private compute + +Store private data + +Build blocks on other chains + +
+ +Interface with many different MEV components, meaning that you can + + + + Plug into existing MEV infra: i.e sending bundles to block builders, relays, validators or sequencers + + Build totally new MEV infra: i.e. create unique SUAPPs on SUAVE + + + +
+ +
\ No newline at end of file diff --git a/docs/concepts/mev-supplychain-interface.mdx b/docs/concepts/mev-supplychain-interface.mdx new file mode 100644 index 00000000..f5512a66 --- /dev/null +++ b/docs/concepts/mev-supplychain-interface.mdx @@ -0,0 +1,69 @@ +--- +title: MEV Supply Chain Interface +description: How SUAVE enables you to interact with virtually any component that has anything to do wih MEV +--- + +The previous pages in this section have illustrated how you can use SUAVE to build blocks for other chains, how to use confidential computation in various different ways depending on your use case, and how to leverage confidential data storage to create a service that is currently run in a centralized way on a decentralized and permissionless network. + +Taken together, these three broad categories of the unique features of SUAVE should illustrate that you can use SUAVE to interact with whatever component in the MEV supply chain you want are most interested in and/or think is the most profitable. + +At a first approximation, the MEV supply chain looks like this: + +![MEV Supply Chain - Linear Version](/img/mev-supplychain.png) + +The point of this section has been to illustrate that SUAPPs can interact with any of these components. + +### Off-SUAVE interaction + +```solidity + function submitBundleJsonRPC(string memory url, string memory method, bytes memory params) internal view returns (bytes memory) + function submitEthBlockToRelay(string memory relayUrl, bytes memory builderBid) internal view returns (bytes memory) + function doHTTPRequest(HttpRequest memory request) internal view returns (bytes memory) +``` + +We've already seen in the previous tutorial, which looked at the [Private OFA Suapp](https://github.com/flashbots/suapp-examples/blob/main/examples/app-ofa-private/ofa-private.sol) example contract, how to create bundles and send them to a predefined block builder using the `submitBundleJsonRPC()` precompile. + +Similarly speaking, you can construct the whole block yourself and send it to a builder using `submitEthBlockToRelay()`. Taken together, these two precompiles allow you to interface with the **transaction**, **bundle**, and **block** aspects of the supply chain above. + +Furthermore, there is a `doHTTPRequest()` precompile, which enables Kettles to make any arbitrary http request in order to fetch information from other services they're running on different chains, or just about any other API they need to handle their off chain computation. An example of this in use can also be found in the Private OFA Suapp Example, and it looks like this: + +```solidity +function submitBundle(string memory builderUrl, bytes memory bundleData) internal view returns (bytes memory) { + // encode the jsonrpc request in JSON format. + bytes memory body = + abi.encodePacked('{"jsonrpc":"2.0","method":"mev_sendBundle","params":[', bundleData, '],"id":1}'); + + Suave.HttpRequest memory request; + request.url = builderUrl; + request.method = "POST"; + request.body = body; + request.headers = new string[](1); + request.headers[0] = "Content-Type: application/json"; + request.withFlashbotsSignature = true; + + return Suave.doHTTPRequest(request); +} +``` + +### On SUAVE interaction + +```solidity + function confidentialStore(DataId dataId, string memory key, bytes memory value) internal view + function confidentialRetrieve(DataId dataId, string memory key) internal view returns (bytes memory) +``` + +The Private OFA examples also illustrates how the confidential store, and the various on chain interactions in enables, may be used to interface with **every aspect** of the supply chain, right from user intents to bundles and blocks. + +The below visualization demonstrate the generalized form such Suapps can take as SUAVE matures, illustrating how the OFA contract could key values into the confidential store such that a block building contract could fetch them and use them to create and emit valid blocks (this would require, among other things, extending the **allowedPeekers** we set in [the previous page](/concepts/confidential-data-storage#practical-example)): + +![OFA to Block Flow](/assets/OFA_And_Block_Flow.svg) + +### MEV supply network + +Of course, the reality of MEV is a bit more complex than the linear supply chain we have shown above. It may well look something more like this (taken with thanks from [here](https://frontier.tech/infinite-games)): + +![MEV Supply Network](/img/mev-supply-network.png) + +Although SUAVE is still in early alpha, one of our goals is to enable full programmable interaction with every component in the above network, such that we can create a genuinely open and permissionless marketplace of different mechanisms that mitigate MEV. + +For practical examples of what it looks like to encode current products and services as smart contracts on SUAVE, please consult the [`suave-std` library tutorial](/tutorials/suave-standard-library#mevshare). \ No newline at end of file diff --git a/docs/design-goals.mdx b/docs/design-goals.mdx deleted file mode 100644 index 33186f44..00000000 --- a/docs/design-goals.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Design Goals -description: SUAVE design goals to help the search for universality -keywords: - - flashbots - - suave - - design goals ---- - -We draw on the theoretical goals outlined in "[Strategyproof Computing](https://groups.ischool.berkeley.edu/archive/p2pecon/papers/s1-ng.pdf)", a paper that illustrates how to think about incentives in the design of distributed systems: - -``` -1. Incentives-first -2. Utility-based -3. Simple -4. Open -5. Decentralized -``` - -and the practical ones which led to the implementation of [Serenity](https://notes.ethereum.org/@vbuterin/serenity_design_rationale?type=view#Principles): - -``` -1. Simplicity -2. Long-term stability -3. Sufficiency -4. Defense in depth -5. Full light-client verifiability -``` - -## Permissionless - -It should be possible for anyone to deploy any kind of builder solidity contract. This is inspired by the "open" principle from Strategyproof computing, which states: "Our belief is that an open marketplace will naturally lead to mechanisms with the 'right scope' and 'right complexity'." - -We cannot preempt every kind of MEV that will exist, or the range of methods which can be concocted to extract and distribute it. Therefore, we aim to enable anyone, anywhere to create and deploy novel contracts in response to unpredictable needs. The public nature of these permissionless contracts should help the entire ecosystem remain proactive, as permissionless access should imply a contestable marketplace of designs. - -- [Searching for Universality](https://docs.google.com/file/d/1c0Ok4M3CcPjMCh7-vh6ErfhqlJsh1qau/edit?filetype=mspresentation) - -## Simple - -Strategyproof computing argues that we ought to "simplify the decisions facing participants in distributed multi-agent systems", and Vitalik points out that simplicity matters "because it (i) minimizes development costs, (ii) reduces risk of unforeseen security issues, and (iii) allows protocol designers to more easily convince users that parameter choices are legitimate". - -Simplicity implies flexibility with respect to dependencies, such that we can upgrade from SGX to MPC, or deploy better cryptographic solutions like FHE, or introduce some maximally robust and sufficiently decentralized combination of the above. - -- [Simplicity Matters](https://youtu.be/rI8tNMsozo0) - -## Sufficient - -This is inspired by the Serenity design rationale, which states that it should be "possible to build as many classes of applications as possible on top of the protocol". - -We strive for the same generality with SUAVE: it should be possible to use SUAVE to create any kind of application to do with order flow, block building, commitments, instantaneous privacy, and any other MEV application we have yet to imagine. - -- [Information is the new money](https://www.youtube.com/watch?v=vi-rVTFTb6s) - -## Private - -The operation of mechanisms for ordering information and distributing value must be public and verifiable. The data which passes through those mechanisms must not be. Privacy is a human right and, in the context of MEV, it enables us to create more economically efficient systems that are resilient to centralization of wealth and power over time, and to malicious manipulation in any given moment. - -We must provide people with the ability to keep their data hidden and only reveal it to those whom they trust or wish to interact with. - -## Decentralized - -Allocating resources without a central authority is hard because there is a trade-off between revenue optimality and efficiency. People should benefit maximally from their information, and finding or correcting inefficiencies should carry sufficient reward. - -SUAVE is simultaneously a search for the most efficient mechanisms for value extraction, and the most optimal mechanisms for value distribution. How such mechanisms work cannot be invented in isolation, it must be discovered together (like the price in an auction). No-one should have undue power in this process of discovery. SUAVE unifies insights from information theory, computer science, economics, and sociopolitics to ensure such power remains properly decentralized. - -- [The holy grail](https://youtu.be/vi-rVTFTb6s?t=1092) - -## Credible - -This is inspired by Strategyproof computing, which states that, "the self-interest of participants in distributed systems should be explicitly addressed by system designers." - -It should be possible to quantify who benefits, and how much they benefit relative to the average. - -- [Towards a Theory of MEV: Uncertainty](https://www.youtube.com/watch?v=WYH7n4M016A&t=14626s) - -We do not mean "who" in the personal sense, but rather in terms of the type of actors involved. Specifically, users should enjoy the maximum value possible while ensuring SUAVE is adopted by all parties, with the rest of that value cascading down to those doing the most relevant work. - -- [MEV Precedence List](https://youtu.be/6oFNYDBH76Q?t=464) diff --git a/docs/index.mdx b/docs/index.mdx index ae28247c..5f74abfa 100644 --- a/docs/index.mdx +++ b/docs/index.mdx @@ -164,9 +164,7 @@ You can find us in our [Forum](https://collective.flashbots.net/c/suave/27) and
Flashbots Suave Forum
-
- Discuss your thoughts and ideas with the community -
+
Discuss your thoughts and ideas with the community
@@ -189,4 +187,4 @@ You can find us in our [Forum](https://collective.flashbots.net/c/suave/27) and - + \ No newline at end of file diff --git a/docs/resources/forge.mdx b/docs/resources/forge.mdx index 6467ef9e..924363a7 100644 --- a/docs/resources/forge.mdx +++ b/docs/resources/forge.mdx @@ -3,135 +3,96 @@ title: Forge description: Use Forge to help develop and test contracts with new precompiles on SUAVE --- -:::info - -There is limited support for Forge in SUAVE. We recommend that you use it only for writing contracts intended to test precompiles. - -::: - Writing and compiling contracts for SUAVE is similar to Ethereum, and can be done with familiar local tools like Forge, or even IDEs like Remix. Deploying those contracts to SUAVE is done using the same transaction type as Ethereum, and so can also be achieved from those tools without modifying anything other than the RPC endpoint. -However, SUAVE makes an [extended set of precompiles](/technical/specs/rigil/precompiles) available in any contract. While these are included as a [library](https://github.com/flashbots/suave-geth/blob/main/suave/sol/libraries/Suave.sol) to keep compilation easy, you can't use Forge (or Remix) to interact with any method in those contracts which uses any of the new precompiles once the contracts are deployed. - -Methods which use new precompiles can only be executed through a Kettle as a Confidential Compute Request (CCR). Foundry supports neither precompiles nor CCRs. This limits the current use cases for Forge. +SUAVE makes an [extended set of precompiles](/technical/specs/rigil/precompiles) available in any contract. -[`SuaveForge.sol`](https://github.com/flashbots/suave-geth/blob/main/suave/sol/libraries/SuaveForge.sol) is a Solidity library that implements the same precompiles as `Suave.sol`. The difference is this: +In order to make interacting with these precompiles easier, we maintain a repository of contracts and libraries called [`suave-std`](https://github.com/flashbots/suave-std). -- `Suave.sol` is used in the MEVM on the Kettle specified by any CCR -- `SuaveForge.sol` uses the [ffi](https://book.getfoundry.sh/cheatcodes/ffi) cheatcode in an environment external to Forge (i.e. the instance of SUAVE you are running locally). The `ffi` cheatcode uses the `suave forge` command from the `suave` binary to make remote calls. +## Suapp examples -## Install - -Let's start a new, empty repo and set `suave-geth` as a submodule so that we can easily import the `SuaveForge.sol` library: +The easiest way to start creating your own contracts with Forge is to clone the [Suapp Examples repo](https://github.com/flashbots/suapp-examples/), as it comes with `suave-std` already set up as a submodule, as well as a series of examples that use both Forge and the Golang SDK. ```bash -mkdir suave-forge +git clone git@github.com:flashbots/suave-std.git && cd suapp-examples ``` ```bash -cd suave-forge +git submodule init && git submodule update ``` -```bash -forge init -``` +## Encoding and Decoding Transactions -```bash -git submodule init -``` - -```bash -git submodule add https://github.com/flashbots/suave-geth.git -``` +`suave-std` is intended to implement core functionality that is likely to be used often by many different kinds of Suapps. One such example of this is encoding and decoding transactions from other chains, which you may need to do when matching different transactions in an order flow auction, or turning bundles into (partial) blocks in a block building contract, or weaving together different transactions on different chains for your unique use case. -## Write and run a Forge script - -Here is an example Forge script that uses the `SuaveForge.sol` library to create a new bid. Copy and paste it into a file called `Example.sol` in the `src` directory: +Having to encode and decode such transactions is a pain, which is exactly the sort of scenario where `suave-std` can help: ```solidity -pragma solidity ^0.8.8; - -import "../suave-geth/suave/sol/libraries/SuaveForge.sol"; -import "forge-std/Script.sol"; - -contract Example is Script { - address[] public addressList = [Suave.ANYALLOWED]; - - function run() public { - Suave.DataRecord memory record = SuaveForge.newDataRecord( - 0, - addressList, - addressList, - "default:v0:ethBundles" - ); - - Suave.DataRecord[] memory allShareMatchRecords = SuaveForge.fetchDataRecords( - 0, - "default:v0:ethBundles" - ); - console.log(allShareMatchRecords.length); - - SuaveForge.confidentialStore(record.id, "a", abi.encodePacked("bbbbbb")); - bytes memory result = SuaveForge.confidentialRetrieve(record.id, "a"); - console.logBytes(result); +import "suave-std/Transactions.sol"; + +contract Example { + function example() { + Transactions.Legacy memory legacyTxn0 = Transactions.Legacy({ + to: address(0x095E7BAea6a6c7c4c2DfeB977eFac326aF552d87), + gas: 50000, + gasPrice: 10, + value: 10, + ... + }); + + // Encode to RLP + bytes memory rlp = Transactions.encodeRLP(legacyTxn0); + + // Decode from RLP + Transactions.Legacy memory legacyTxn1 = Transactions.decodeRLP(rlp); } } ``` -The same precompile functions available in `Suave.sol` are also implemented in `SuaveForge.sol`, though the struct types are still imported from `Suave.sol`. It is not required to import `Suave.sol` in your scripts since `SuaveForge.sol` already does it. +It can also be difficult to test specific precompiles when using Forge. In order to make this possible, `suave-std` provides a "SUAVE-enabled" test contract, which you can import and use like this: -In order to deploy this example contract, you need to have [SUAVE running locally](/tutorials/run-suave/), which can be done from your git submodule directory: +```solidity +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.13; -```bash -cd suave-geth -``` +import "forge-std/Test.sol"; +import "suave-std/Test.sol"; +import "suave-std/Suave.sol"; -```bash -make suave -``` +contract TestForge is Test, SuaveEnabled { + address[] public addressList = [0xC8df3686b4Afb2BB53e60EAe97EF043FE03Fb829]; -```bash -suave --suave.dev -``` + function testConfidentialStore() public { + Suave.DataRecord memory record = Suave.newDataRecord(0, addressList, addressList, "namespace"); -Then, run the Forge script with the `ffi` flag enabled: + bytes memory value = abi.encode("suave works with forge!"); + Suave.confidentialStore(record.id, "key1", value); -```bash -forge script Example.sol --ffi + bytes memory found = Suave.confidentialRetrieve(record.id, "key1"); + assertEq(keccak256(found), keccak256(value)); + } +} ``` -
- Having issues? -
-
-
- Typically, building SUAVE yourself places the binary in the $GOPATH/bin - directory. If it didn't happen, ensure that path is added to your PATH - environment variable:
-
-
export PATH=\$PATH\:$GOPATH\/bin
-
-
-
-
+You will need to have [SUAVE running locally](/tutorials/run-suave) in order to be able to run such a test successfully. -The Forge script should print the gas used to run the specified function in your console. If you check the logs of your SUAVE devnet, you should see a message like this: +### Deploying Contracts -`INFO [timestamp] confidential engine: refusing to send writes based on unsigned transaction` +In order to deploy any contract you write in the SUAPP Example repo, you need to either have [SUAVE running locally](/tutorials/run-suave/), or an account on Rigil with some [rETH from the faucet](https://faucet.rigil.suave.flashbots.net). -Due to the limitations described above (no native support for precompiles or CCRs in Forge) and having to rely on your local environment, rather than Foundry's built-in network or forks, we recommend that you only use Forge for testing new precompiles you are writing. +To deploy on Rigil using Forge, you can run the below: -## Deploy your contract - -That said, you can use Forge to deploy contracts to SUAVE (though we recommend that you then use the [Golang SDK](/resources/golang-sdk) to send transactions). - -If you wanted to deploy `Example.sol`, there are three steps you need to take: +```bash +forge create --rpc-url https://rpc.rigil.suave.flashbots.net --legacy \ +--private-key examples/app-ofa-private/ofa-private.sol:OFAPrivate +``` -1. Replace `SuaveForge.sol` with `Suave.sol` and update all references in your contract. -2. Get [Rigil ETH from the faucet](https://faucet.rigil.suave.flashbots.net). -3. Run the following command: +In order to deploy locally, you can can change the rpc and private key values: ```bash -forge create --rpc-url https://rpc.rigil.suave.flashbots.net --legacy \ ---private-key src/Example.sol:Example +forge create --rpc-url http://localhost:8545 --legacy \ +--private-key 0x91ab9a7e53c220e6210460b65a7a3bb2ca181412a8a7b43ff336b3df1737ce12 \ +examples/app-ofa-private/ofa-private.sol:OFAPrivate ``` + +You should also note, if you look at the other examples, how the [Golang SDK](/resources/golang-sdk) is used not only to deploy contracts, but test various kinds of transactions in order to illustrate how each contract is intended to function. Using the Golang SDK can provide for significantly more flexibility than just deploying your contract via Forge. diff --git a/docs/sidebars.js b/docs/sidebars.js index 7c9660f1..426a81c4 100644 --- a/docs/sidebars.js +++ b/docs/sidebars.js @@ -19,6 +19,7 @@ module.exports = { items: [ 'tutorials/run-suave', 'tutorials/deploy-contracts', + 'tutorials/suave-standard-library', 'tutorials/build-suapps', 'tutorials/confidential-compute-requests', 'tutorials/create-precompiles', @@ -30,10 +31,22 @@ module.exports = { collapsed: false, link: {type: 'doc', id: 'resources/index'}, items: [ + { + type: 'category', + label: 'How SUAVE Extends Solidity', + collapsed: true, + link: {type: 'doc', id: 'concepts/index'}, + items: [ + 'concepts/block-building', + 'concepts/confidential-computation', + 'concepts/confidential-data-storage', + 'concepts/mev-supplychain-interface' + ], + }, 'resources/rigil', 'resources/forge', 'resources/golang-sdk', - 'resources/typescript-sdk', + 'resources/typescript-sdk' ], }, { diff --git a/docs/technical b/docs/technical index 738a346d..95f36493 160000 --- a/docs/technical +++ b/docs/technical @@ -1 +1 @@ -Subproject commit 738a346d8f1a6ae58cadc13d22187be3f2b204f8 +Subproject commit 95f36493ec344fda29976ea5a72b8d8c17bd7333 diff --git a/docs/tutorials/build-suapps.mdx b/docs/tutorials/build-suapps.mdx index 6cd2d478..17eccf8d 100644 --- a/docs/tutorials/build-suapps.mdx +++ b/docs/tutorials/build-suapps.mdx @@ -1,6 +1,6 @@ --- title: Build SUAPPs -description: Create your first aplication on SUAVE +description: Create your first application on SUAVE keywords: - application - build @@ -12,7 +12,7 @@ keywords: # Build SUAPPs -This tutorial will show you how to build a SUAPP using `suave-viem`, our [typescript SDK](/resources/typescript-sdk), and two different [SUAPP example contracts](https://github.com/flashbots/suapp-examples/). +This tutorial will show you how to build a SUAPP using `suave-viem`, our [typescript SDK](/resources/typescript-sdk). :::info diff --git a/docs/tutorials/confidential-compute-requests.mdx b/docs/tutorials/confidential-compute-requests.mdx index bff07e0e..4566a3ee 100644 --- a/docs/tutorials/confidential-compute-requests.mdx +++ b/docs/tutorials/confidential-compute-requests.mdx @@ -10,7 +10,7 @@ keywords: :::info -There are a number of different ways to work with SUAVE and to craft Confidential Compute Requests (CCRs). We'll discuss how to use both the Typsecript and Golang SDKs in this tutorial. +There are a number of different ways to work with SUAVE and to craft Confidential Compute Requests (CCRs). We'll discuss how to use both the Typescript and Golang SDKs in this tutorial. ::: @@ -22,7 +22,7 @@ There are a number of different ways to work with SUAVE and to craft Confidentia
Typescript
-
For web devs
+
For web developers
@@ -62,7 +62,9 @@ The **Typescript** template will lead you through how to sign a transaction on a ### Callbacks -Let's therefore start in the [Next template](https://github.com/andytudhope/build-a-suapp-next-ts/) and look at how CCRs work and how to use them. [`OnChainState.sol`](https://github.com/andytudhope/build-a-suapp-next-ts/blob/main/packages/forge/src/OnChainState.sol) demonstrates that any CCR which tries to change state directly will revert. Rather, you need to use a callback to a different function that does change state in order to ensure that data sent in a CCR does remain confidential: +Let's start in the [Next template](https://github.com/andytudhope/build-a-suapp-next-ts/) and look at how CCRs work and how to use them. + +[`OnChainState.sol`](https://github.com/andytudhope/build-a-suapp-next-ts/blob/main/packages/forge/src/OnChainState.sol) demonstrates that any CCR which tries to change state directly will revert. Rather, you need to use a callback to a different function that does change state in order to ensure that data sent in a CCR remains confidential: ```solidity // nilExample is a function executed in a confidential request @@ -119,7 +121,7 @@ There are a few key points to understand: 1. You need to enable "Eth_sign" in the Advanced settings in your browser wallet for this to work. 2. We can leave the `confidentialInputs` field empty, as we're not actually sending any data along with this transaction: just demonstrating how CCRs work. -3. We specify a new type for the transaction. The [different `suave-viem` transactionx types are defined here](https://github.com/flashbots/suave-viem/blob/main/src/chains/suave/types.ts). +3. We specify a new type for the transaction. The [different `suave-viem` transaction types are defined here](https://github.com/flashbots/suave-viem/blob/main/src/chains/suave/types.ts). 5. The `suaveWallet.sendTransaction(ccr)` uses `eth_sign` under the hood, along with a few other steps required to serialize the transaction correctly, which you can see happening [here](https://github.com/flashbots/suave-viem/blob/main/src/chains/suave/wallet.ts). ### CCRs with data @@ -192,20 +194,20 @@ The flow of this example is similar to the Typescript MEVShare demo directly abo 1. Deploy the OFA contract. 2. Instantiate two new accounts and fund them. 3. Craft two different transactions: `ethTxn1` which simulates a transaction from another domain, and `ethTxnBackrun` which simulates a backrun based on the hint emitted by `ethTxn1`. -4. Wrap the first transaction into a "bundle", add any extra data required (in this case, just the percentage of MEV the user is willing to share with whomever includes their transaction), and send it to the OFA contract from the first account. +4. Wrap the first transaction into a "bundle", add any extra data required (in this case, just the percentage of MEV the user is willing to share with whomever includes their transaction), and send it to the OFA contract on SUAVE. 1. Receive and store the hint event that is emitted as a result of the transaction. 5. Wrap the second transaction into another bundle and send it to the OFA contract (along with extra data like the hint event ID). 1. Receive and store the match event in the case that the contract does batch the transactions together. 6. Send that resulting batch of matched transactions to a known relayer off-chain so that it can be included on the intended domain. -In order to create a signed transaction, you can use the Golang SDK like this: +In order to create a signed transaction on Ethereum L1, you can use the Golang SDK like this: ```go -ethTxn1, _ := fr.SignTx(testAddr1, &types.LegacyTx{ - To: &targeAddr, - Value: big.NewInt(1000), - Gas: 21000, - GasPrice: big.NewInt(13), +ethTxn1, _ := fr.L1.SignTx(testAddr1, &types.LegacyTx{ + To: &targeAddr, + Value: big.NewInt(1000), + Gas: 21000, + GasPrice: big.NewInt(670189871), }) ``` @@ -220,12 +222,12 @@ bundle := &types.SBundle{ bundleBytes, _ := json.Marshal(bundle) ``` -In order to send a transaction from a specific account to a specific contract, passing in particular arguments and storing the resulting receipt, you would use something like this: +In order to send this bundle to the contract on SUAVE, passing in particular arguments and storing the resulting receipt, we do this: ```go -receipt = contractAddr2.SendTransaction("newMatch", []interface{}{hintEvent.DataRecordId}, backRunBundleBytes) +receipt = contract.SendTransaction("newMatch", []interface{}{hintEvent.DataRecordId}, backRunBundleBytes) ``` -We can visualise the most general form of this example (involving multiple different transactions types, actors, and actions) like this: +We can visualize the most general form of this example (involving multiple different transactions types, actors, and actions) like this: ![OFA](/assets/OFA_And_Block_Flow.svg) \ No newline at end of file diff --git a/docs/tutorials/create-precompiles.mdx b/docs/tutorials/create-precompiles.mdx index 221d0f22..ff34855b 100644 --- a/docs/tutorials/create-precompiles.mdx +++ b/docs/tutorials/create-precompiles.mdx @@ -15,7 +15,7 @@ Creating precompiles requires writing lower level code than the contracts and tr ::: -SUAVE uses [custom precompiles](/technical/specs/rigil/precompiles) to extend the EVM with specific MEV functions. Unless you have a very specific usecase, building a SUAPP should not require writing precompiles. +SUAVE uses [custom precompiles](/technical/specs/rigil/precompiles) to extend the EVM with specific MEV functions. Unless you have a very specific use case, building a SUAPP should not require writing precompiles. In this tutorial, we will add a new precompile to the [suave-geth client](https://github.com/flashbots/suave-geth) that will be accessible in any builder solidity contract on SUAVE. diff --git a/docs/tutorials/deploy-contracts.mdx b/docs/tutorials/deploy-contracts.mdx index d0237f0f..7c507432 100644 --- a/docs/tutorials/deploy-contracts.mdx +++ b/docs/tutorials/deploy-contracts.mdx @@ -14,7 +14,7 @@ import RPCButton from '@site/src/components/RPCButton/index'; :::info -SUAVE contracts can be deployed using all existing Ethereum client providers (ethers, viem, geth...) and development tool kits (forge, hardhat, brownie...). +SUAVE contracts can be deployed using all existing Ethereum client providers (ethers, viem, geth...) and development tool kits (forge, hardhat, brownie...). We maintain a [**SUAPP examples repo**](https://github.com/flashbots/suapp-examples/) of contracts to help you get started. ::: @@ -153,7 +153,7 @@ The `framework.go` and all of the `main.go` files use the Golang SDK, which you ### To Rigil -If you'd like to deploy one of these contracts to the Rigil Testnet instea, first ensure that you have rETH for the account you want to use from the [Rigil ETH Faucet](https://faucet.rigil.suave.flashbots.net). +If you'd like to deploy one of these contracts to the Rigil Testnet instead, first ensure that you have rETH for the account you want to use from the [Rigil ETH Faucet](https://faucet.rigil.suave.flashbots.net). Then, edit the `DefaultConfig` of `framework/framework.go` to look like this (with the private key replaced): diff --git a/docs/tutorials/suave-standard-library.mdx b/docs/tutorials/suave-standard-library.mdx new file mode 100644 index 00000000..88f223f4 --- /dev/null +++ b/docs/tutorials/suave-standard-library.mdx @@ -0,0 +1,100 @@ +--- +title: SUAVE Standard Library +description: A collection of contracts and libraries to empower SUAPP developers and make life easier for builders. +keywords: + - application + - build + - suave + - solidity +--- + +import List from '@site/src/components/List/List.tsx'; + +[suave-std](https://github.com/flashbots/suave-std) is a collection of Solidity contracts and libraries to help you create Suapps. It is included as a submodule in the [SUAPP Examples](https://github.com/flashbots/suapp-examples/) repo, which we used in the previous tutorial. + +In this tutorial, we will be diving deeper into the different capabilities offered by `suave-std`. + +:::info + +`suave-std` is the main entrypoint for developers who are interacting with SUAVE. It is a place to create building blocks, sdks, and common patterns that are useful to SUAVE developers. + +::: + +The core functionalities that `suave-std` will help you handle include: + + + +transaction parsing and construction + +JSON object decoding and encoding + +convenience wrapper around precompiles + + + +## Transactions + +One such example of this is encoding and decoding transactions from other chains, which you may need to do when matching different transactions in an order flow auction, or turning bundles into (partial) blocks in a block building contract, or weaving together different transactions on different chains for your unique use case. + +Having to encode and decode such transactions is a pain, which is exactly the sort of scenario where `suave-std` can help: + +```solidity +import "suave-std/Transactions.sol"; + +contract Example { + function example() { + Transactions.Legacy memory legacyTxn0 = Transactions.Legacy({ + to: address(0x095E7BAea6a6c7c4c2DfeB977eFac326aF552d87), + gas: 50000, + gasPrice: 10, + value: 10, + ... + }); + + // Encode to RLP + bytes memory rlp = Transactions.encodeRLP(legacyTxn0); + + // Decode from RLP + Transactions.Legacy memory legacyTxn1 = Transactions.decodeRLP(rlp); + } +} +``` + +## SUAVE Enabled Tests + +It can also be difficult to test specific precompiles when using Forge. In order to make this possible, `suave-std` provides a "SUAVE-enabled" test contract, which you can import and use like this: + +```solidity +// SPDX-License-Identifier: Unlicense +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; +import "suave-std/Test.sol"; +import "suave-std/Suave.sol"; + +contract TestForge is Test, SuaveEnabled { + address[] public addressList = [0xC8df3686b4Afb2BB53e60EAe97EF043FE03Fb829]; + + function testConfidentialStore() public { + Suave.DataRecord memory record = Suave.newDataRecord(0, addressList, addressList, "namespace"); + + bytes memory value = abi.encode("suave works with forge!"); + Suave.confidentialStore(record.id, "key1", value); + + bytes memory found = Suave.confidentialRetrieve(record.id, "key1"); + assertEq(keccak256(found), keccak256(value)); + } +} +``` + +## MevShare + +While not yet in the main branch of `suave-geth`, the [MevShare library](https://github.com/flashbots/suave-geth/blob/feature/suave-std/suave/sol/suave-std/mevshare.sol) illustrates all of the major functionality we've discussed so far. + +## MevBoost + +The same is true for the [MevBoost library](https://github.com/flashbots/suave-geth/blob/feature/suave-std/suave/sol/suave-std/mevboost.sol). + +The goal of these two libraries is to illustrate how products and services which currently rely on a known set of actors to run can be encoded as smart contracts on SUAVE, and made to work on an open, permissionless network. + +It is in this sense that we make the claim that applications built on SUAVE can interface with any component in the [MEV supply network](/concepts/mev-supplychain-interface). \ No newline at end of file diff --git a/docs/what-is-suave.mdx b/docs/what-is-suave.mdx index 03bba4be..8715032e 100644 --- a/docs/what-is-suave.mdx +++ b/docs/what-is-suave.mdx @@ -70,7 +70,7 @@ To access private state, we use "Confidential Compute Requests". A SUAPP is a smart contract deployed on SUAVE, just as a Dapp is a smart contract deployed on Ethereum. [Deploying contracts](/tutorials/deploy-contracts) is largely the same as any EVM chain. -Transactions are different, because they can contain data encrypted for specific actors (i.e. Kettles and/or other contracts). These are the ["Confidential Compute Requests"](/tutorials/build-suapps#working-with-ccrs). +Transactions are different, because they can contain data encrypted for specific actors (i.e. Kettles and/or other contracts). These are the ["Confidential Compute Requests"](/tutorials/confidential-compute-requests). Confidential Compute Requests are handled via a modified RPC in each Kettle. They allow you to control how much data ends up back on-chain. diff --git a/project-words.txt b/project-words.txt index bf3e6db3..0f2c9782 100644 --- a/project-words.txt +++ b/project-words.txt @@ -1,13 +1,18 @@ +andytudhope +backruns +bhvy camelcase dogfood flashbot flashbots Flashbots hideable -Inpage +ipcpath katex rehype stylelint +suapps +supplychain tailwindcss ANYALLOWED @@ -19,16 +24,25 @@ Errorf Fairier Frites Infima +Inpage JSOPN LNBQY +Mehran MEVM +Miha +Miha's MISDELIVERY +NFTEE OFAC OFSI Ragu +Randao Rollups SAUVE SUAPP +SUAPPs +Suapp +Suapps Sprintf Strategyproof Tarun diff --git a/static/img/mev-supply-network.png b/static/img/mev-supply-network.png new file mode 100644 index 00000000..5970960a Binary files /dev/null and b/static/img/mev-supply-network.png differ diff --git a/static/img/mev-supplychain.png b/static/img/mev-supplychain.png new file mode 100644 index 00000000..ffac22e6 Binary files /dev/null and b/static/img/mev-supplychain.png differ