Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions examples/tx-observability/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# tx observability

Opt into a standardized set of events ([TBD](https://github.com/flashbots/suave-std/pull/85)) to enable interoperability with other SUAPPS, block-builders, L2 networks, etc.

Events are defined in an abstract contract (ideally in suave-std):

```solidity
abstract contract ObservableOrderflow {
event SentTransaction(bytes32 txHash);
}
```

Then SUAPP developers import and emit those events in their own callbacks:

```solidity
contract Suapp is ObservableOrderflow {
event MySuappEvent(uint256 x);

modifier confidential() {
require(Suave.isConfidential(), "must be called confidentially");
_;
}

function didSomething(bytes32[] memory txHashes, uint256 x) public confidential {
emit MySuappEvent(x);
emit SentTransactions(txHashes);
}

function doSomething() public confidential returns (bytes memory) {
// pretend these are tx hashes that we're handling in our SUAPP
bytes32[] memory txHashes = new bytes32[](3);
for (uint256 i = 0; i < txHashes.length; i++) {
txHashes[i] = keccak256(abi.encode("tx", i));
}
return abi.encodeWithSelector(this.didSomethingWithTxs.selector, txHashes, 9001);
}
}
```
30 changes: 30 additions & 0 deletions examples/tx-observability/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"log"

"github.com/ethereum/go-ethereum/common"
"github.com/flashbots/suapp-examples/framework"
)

// SentTransactionsEvent is emitted by SUAPPs to indicate that the SUAPP sent some transactions to L1.
type SentTransactionsEvent struct {
TxHashes []common.Hash `abi:"txHashes"`
}

func main() {
fr := framework.New(framework.WithL1())
suappContract := fr.Suave.DeployContract("observability.sol/Suapp.json")

res := suappContract.SendConfidentialRequest("doSomethingWithTxs", nil, nil)
if res.Status != 1 {
log.Fatal("confidential request failed")
}

var event SentTransactionsEvent
err := suappContract.Abi.UnpackIntoInterface(&event, "SentTransactions", res.Logs[0].Data)
if err != nil {
log.Fatalf("Failed to unpack log data: %v", err)
}
log.Printf("logged tx hashes: %v", event.TxHashes)
}
29 changes: 29 additions & 0 deletions examples/tx-observability/observability.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import "suave-std/suavelib/Suave.sol";

// This could be added to suave-std so that all SUAPPs can use it.
abstract contract TxSender {
event SentTransactions(bytes32[] txHashes);
}

contract Suapp is TxSender {
modifier confidential() {
require(Suave.isConfidential(), "must be called confidentially");
_;
}

function didSomethingWithTxs(bytes32[] memory txHashes) public confidential {
emit SentTransactions(txHashes);
}

function doSomethingWithTxs() public confidential returns (bytes memory) {
// pretend these are tx hashes that we're handling in our SUAPP
bytes32[] memory txHashes = new bytes32[](3);
for (uint256 i = 0; i < txHashes.length; i++) {
txHashes[i] = keccak256(abi.encode("tx", i));
}
return abi.encodeWithSelector(this.didSomethingWithTxs.selector, txHashes);
}
}
2 changes: 0 additions & 2 deletions framework/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,6 @@ func (c *Contract) SendConfidentialRequest(method string, args []interface{}, co
panic(err)
}

log.Printf("transaction hash: %s", txnResult.Hash().Hex())

receipt, err := txnResult.Wait()
if err != nil {
panic(err)
Expand Down