Skip to content

Commit

Permalink
improve visibility config (#2066)
Browse files Browse the repository at this point in the history
* improve visibility config

* better comments and small fix

* clarifications
  • Loading branch information
tudor-malene authored Oct 1, 2024
1 parent ae384cd commit 9888300
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 52 deletions.
22 changes: 15 additions & 7 deletions contracts/src/lib/ContractTransparencyConfig.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,26 @@ pragma solidity ^0.8.20;
// implement this interface if you want to configure the visibility rules of your smart contract
// the TEN platform will interpret this information
interface ContractTransparencyConfig {
// configuration per event log type
enum Field{
TOPIC1, TOPIC2, TOPIC3, // if any of these fields is in the relevantTo array, then the address in that topic will be able to query for that event
SENDER, // the tx.origin will be able to query for the event
EVERYONE // the event is public - visible to everyone
}

enum ContractCfg{
TRANSPARENT, //the internal state via getStorageAt will be accessible to everyone. All events will be public. This is the strongest setting.
PRIVATE // internal state is hidden, and events can be configured.
}

// configuration per event log type
struct EventLogConfig {
bytes eventSignature;
bool isPublic; // everyone can see and query for this event
bool topic1CanView; // If the event is private, and this is true, it means that the address from topic1 is an EOA that can view this event
bool topic2CanView; // same
bool topic3CanView; // same
bool visibleToSender; // if true, the tx signer will see this event. Default false
bytes32 eventSignature;
Field[] visibleTo;
}

struct VisibilityConfig {
bool isTransparent; // If true - the internal state via getStorageAt will be accessible to everyone. All events will be public. Default false
ContractCfg contractCfg;
EventLogConfig[] eventLogConfigs; // mapping from event signature to visibility configs per event
}

Expand Down
25 changes: 17 additions & 8 deletions go/enclave/evm/ContractTransparency.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,24 +28,33 @@ var (
_ = abi.ConvertType
)

const (
topic1 uint8 = iota
topic2
topic3
sender
everyone
)

const (
transparent uint8 = iota
private
)

// ContractTranspMetaData contains all meta data concerning the TransparencyConfig contract.
var ContractTranspMetaData = &bind.MetaData{
ABI: "[{\"inputs\":[],\"name\":\"visibilityRules\",\"outputs\":[{\"components\":[{\"internalType\":\"bool\",\"name\":\"isTransparent\",\"type\":\"bool\"},{\"components\":[{\"internalType\":\"bytes\",\"name\":\"eventSignature\",\"type\":\"bytes\"},{\"internalType\":\"bool\",\"name\":\"isPublic\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"topic1CanView\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"topic2CanView\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"topic3CanView\",\"type\":\"bool\"},{\"internalType\":\"bool\",\"name\":\"visibleToSender\",\"type\":\"bool\"}],\"internalType\":\"structContractTransparencyConfig.EventLogConfig[]\",\"name\":\"eventLogConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structContractTransparencyConfig.VisibilityConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]",
ABI: "[{\"inputs\":[],\"name\":\"visibilityRules\",\"outputs\":[{\"components\":[{\"internalType\":\"enumContractTransparencyConfig.ContractCfg\",\"name\":\"contractCfg\",\"type\":\"uint8\"},{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"eventSignature\",\"type\":\"bytes32\"},{\"internalType\":\"enumContractTransparencyConfig.Field[]\",\"name\":\"visibleTo\",\"type\":\"uint8[]\"}],\"internalType\":\"structContractTransparencyConfig.EventLogConfig[]\",\"name\":\"eventLogConfigs\",\"type\":\"tuple[]\"}],\"internalType\":\"structContractTransparencyConfig.VisibilityConfig\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"pure\",\"type\":\"function\"}]",
}

// ContractTransparencyConfigEventLogConfig is an auto generated low-level Go binding around an user-defined struct.
type ContractTransparencyConfigEventLogConfig struct {
EventSignature []byte
IsPublic bool
Topic1CanView bool
Topic2CanView bool
Topic3CanView bool
VisibleToSender bool
EventSignature common.Hash
VisibleTo []uint8
}

// ContractTransparencyConfigVisibilityConfig is an auto generated low-level Go binding around an user-defined struct.
type ContractTransparencyConfigVisibilityConfig struct {
IsTransparent bool
ContractCfg uint8
EventLogConfigs []ContractTransparencyConfigEventLogConfig
}

Expand Down
48 changes: 36 additions & 12 deletions go/enclave/evm/evm_facade.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,29 +268,53 @@ func readVisibilityConfig(vmenv *vm.EVM, contractAddress *gethcommon.Address) *c
return &core.ContractVisibilityConfig{AutoConfig: true}
}

transp := false
if visibilityRules.ContractCfg == transparent {
transp = true
}

cfg := &core.ContractVisibilityConfig{
AutoConfig: false,
Transparent: &visibilityRules.IsTransparent,
Transparent: &transp,
EventConfigs: make(map[gethcommon.Hash]*core.EventVisibilityConfig),
}

if transp {
return cfg
}

// only check the config for non-transparent contracts
for i := range visibilityRules.EventLogConfigs {
logConfig := visibilityRules.EventLogConfigs[i]
cfg.EventConfigs[logConfig.EventSignature] = eventCfg(logConfig)
}

return cfg
}

sig := gethcommon.Hash{}
sig.SetBytes(logConfig.EventSignature)
func eventCfg(logConfig ContractTransparencyConfigEventLogConfig) *core.EventVisibilityConfig {
relevantToMap := make(map[uint8]bool)
for _, field := range logConfig.VisibleTo {
relevantToMap[field] = true
}
isPublic := relevantToMap[everyone]

cfg.EventConfigs[sig] = &core.EventVisibilityConfig{
AutoConfig: false,
Public: logConfig.IsPublic,
Topic1CanView: &logConfig.Topic1CanView,
Topic2CanView: &logConfig.Topic2CanView,
Topic3CanView: &logConfig.Topic3CanView,
SenderCanView: &logConfig.VisibleToSender,
}
if isPublic {
return &core.EventVisibilityConfig{AutoConfig: false, Public: true}
}

return cfg
t1 := relevantToMap[topic1]
t2 := relevantToMap[topic2]
t3 := relevantToMap[topic3]
s := relevantToMap[sender]
return &core.EventVisibilityConfig{
AutoConfig: false,
Public: false,
Topic1CanView: &t1,
Topic2CanView: &t2,
Topic3CanView: &t3,
SenderCanView: &s,
}
}

func logReceipt(r *types.Receipt, logger gethlog.Logger) {
Expand Down
38 changes: 27 additions & 11 deletions integration/erc20contract/ObsERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,26 @@ import "libs/openzeppelin/contracts/token/ERC20/ERC20.sol";
// implement this interface if you want to configure the visibility rules of your smart contract
// the TEN platform will interpret this information
interface ContractTransparencyConfig {
// configuration per event log type
enum Field{
TOPIC1, TOPIC2, TOPIC3,
SENDER, // tx.origin - msg.sender
EVERYONE // the event is public - visible to everyone
}

enum ContractCfg{
TRANSPARENT, //the internal state via getStorageAt will be accessible to everyone. All events will be public. This is the strongest setting.
PRIVATE // internal state is hidden, and events can be configured.
}

// configuration per event log type
struct EventLogConfig {
bytes eventSignature;
bool isPublic; // everyone can see and query for this event
bool topic1CanView; // If the event is private, and this is true, it means that the address from topic1 is an EOA that can view this event
bool topic2CanView; // same
bool topic3CanView; // same
bool visibleToSender; // if true, the tx signer will see this event. Default false
bytes32 eventSignature;
Field[] visibleTo;
}

struct VisibilityConfig {
bool isTransparent; // If true - the internal state via getStorageAt will be accessible to everyone. All events will be public. Default false
ContractCfg contractCfg;
EventLogConfig[] eventLogConfigs; // mapping from event signature to visibility configs per event
}

Expand Down Expand Up @@ -78,12 +86,20 @@ contract ObsERC20 is ERC20, ContractTransparencyConfig {
}

function visibilityRules() public override pure returns (VisibilityConfig memory){
EventLogConfig[] memory configs = new EventLogConfig[](1);
// erc20 transfer
configs[0] = EventLogConfig(hex"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", false, true, true, false, false);
return VisibilityConfig(false, configs);
bytes32 eventSig = hex"ddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
Field[] memory relevantTo = new Field[](3);
relevantTo[0] = Field.TOPIC1;
relevantTo[1] = Field.TOPIC2;
relevantTo[2] = Field.SENDER;
EventLogConfig[] memory eventLogConfigs = new EventLogConfig[](1);
eventLogConfigs[0] = EventLogConfig(eventSig, relevantTo);
return VisibilityConfig(ContractCfg.PRIVATE, eventLogConfigs);
}

// function visibilityRules() public override pure returns (VisibilityConfig memory){
// return VisibilityConfig(ContractCfg.TRANSPARENT, EventLogConfig[]);
// }

function _beforeTokenTransfer(address from, address to, uint256 amount)
internal virtual override {
//Only deposit messages.
Expand Down
2 changes: 1 addition & 1 deletion integration/erc20contract/abi/ObsERC20.abi
Original file line number Diff line number Diff line change
@@ -1 +1 @@
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"address","name":"busAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"visibilityRules","outputs":[{"components":[{"internalType":"bool","name":"isTransparent","type":"bool"},{"components":[{"internalType":"bytes","name":"eventSignature","type":"bytes"},{"internalType":"bool","name":"isPublic","type":"bool"},{"internalType":"bool","name":"topic1CanView","type":"bool"},{"internalType":"bool","name":"topic2CanView","type":"bool"},{"internalType":"bool","name":"topic3CanView","type":"bool"},{"internalType":"bool","name":"visibleToSender","type":"bool"}],"internalType":"struct ContractTransparencyConfig.EventLogConfig[]","name":"eventLogConfigs","type":"tuple[]"}],"internalType":"struct ContractTransparencyConfig.VisibilityConfig","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"}]
[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint256","name":"initialSupply","type":"uint256"},{"internalType":"address","name":"busAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"visibilityRules","outputs":[{"components":[{"internalType":"enum ContractTransparencyConfig.ContractCfg","name":"contractCfg","type":"uint8"},{"components":[{"internalType":"bytes32","name":"eventSignature","type":"bytes32"},{"internalType":"enum ContractTransparencyConfig.Field[]","name":"visibleTo","type":"uint8[]"}],"internalType":"struct ContractTransparencyConfig.EventLogConfig[]","name":"eventLogConfigs","type":"tuple[]"}],"internalType":"struct ContractTransparencyConfig.VisibilityConfig","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"}]
2 changes: 1 addition & 1 deletion integration/erc20contract/bin/ObsERC20.bin

Large diffs are not rendered by default.

Loading

0 comments on commit 9888300

Please sign in to comment.