Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

improve visibility config #2066

Merged
merged 3 commits into from
Oct 1, 2024
Merged
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
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";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this hash from?

you can do "var visibilityRulesEventSignature = keccak256("preimage")"

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
Loading