Skip to content
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
12 changes: 8 additions & 4 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ jobs:
run: |
uv sync --frozen --no-install-project
npm ci
- name: Install Ape dependencies
run: uv run ape pm install
- name: Ruff
run: uv run ruff check
- name: Prettier
Expand Down Expand Up @@ -60,9 +62,11 @@ jobs:
curl -fsSL "$compiler_url" -o "$compiler_path"
echo "$compiler_sha256 $compiler_path" | sha256sum --check --status
install -m 0755 "$compiler_path" "$solcx_dir/solc-v0.8.34"
- name: Import Brownie network settings
run: uv run brownie networks import data/networks.yml true
- name: Install Ape dependencies
run: uv run ape pm install
- name: Compile contracts
run: uv run brownie compile --all
run: |
uv run ape compile
uv run python tools/json_filter.py
- name: Run tests
run: uv run pytest --disable-warnings -v tests/
run: ANVIL_LOG_FILE=/tmp/secret-escrow-anvil.log bash tests/run_anvil_test.sh tests/ -v
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
!.gitkeep

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down Expand Up @@ -162,5 +164,8 @@ cython_debug/
.idea/

# Project
.build/
build/
reports/
node_modules/
output/
15 changes: 12 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
.PHONY: install update format isort black
.PHONY: install setup update format lint compile test

ANVIL_HOST ?= 127.0.0.1
ANVIL_PORT ?= 8545
ANVIL_LOG_FILE ?= /tmp/secret-escrow-anvil.log
ANVIL_STARTUP_TIMEOUT_SECONDS ?= 30

install:
uv sync --frozen --no-install-project --all-extras
uv run pre-commit install
npm install

setup:
uv run ape pm install

update:
uv lock --upgrade
npm update
Expand All @@ -17,7 +25,8 @@ lint:
uv run ruff check --fix

compile:
brownie compile
uv run ape compile

test:
uv run pytest --network=test_network tests/ --pdb -vv
@ANVIL_HOST=$(ANVIL_HOST) ANVIL_PORT=$(ANVIL_PORT) ANVIL_LOG_FILE=$(ANVIL_LOG_FILE) ANVIL_STARTUP_TIMEOUT_SECONDS=$(ANVIL_STARTUP_TIMEOUT_SECONDS) \
bash tests/run_anvil_test.sh tests/ $(ARG)
23 changes: 15 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@ A prototype implementation of escrow information concealment using Joux's Tripar

- [Python](https://www.python.org/downloads/)
- v3.11
- [Ape Framework](https://www.apeworx.io/ape/stable/)
- We use Ape with the Solidity and Foundry plugins for contract compilation and testing.
- [ethereum/py_ecc](https://github.com/ethereum/py_ecc)
- bls12_381 curve operations
- [Solidity](https://docs.soliditylang.org/)
- We are using Solidity to implement our smart contracts.
- We are using Solidity to implement our smart contracts.
- Currently, we are using v0.8.34.
- [eth-brownie](https://github.com/eth-brownie/brownie)
- We are using the eth-brownie framework for developing and testing our contracts.
- [Anvil](https://www.getfoundry.sh/anvil)
- We use Anvil for local development and unit testing.
- [OpenZeppelin](https://openzeppelin.com/contracts/)
Expand All @@ -33,30 +33,37 @@ Install 3rd party packages.
$ make install
```

Install openzeppelin-contracts.
Install Ape dependencies.
```bash
$ brownie pm install OpenZeppelin/openzeppelin-contracts@4.9.3
$ make setup
```

## Compile Contracts

```bash
$ make compile
```
If the compilation is successful, an ABI will be generated under the `build/` directory.
If compilation succeeds, Ape writes the build manifest under `.build/`.

## Run test

After compiling, Run the following command:
After compiling, run the following command:
```bash
$ make test
```

To run a specific test file:
```bash
$ make test {path_to_test_file}
```

## Developing Smart Contracts

### Network(Anvil) settings

Network settings are defined in the `data/networks.yml` file.
The Ape project settings are defined in `ape-config.yaml`.

The Anvil command used for tests is defined in `tests/run_anvil_test.sh` and uses chain ID `2017` to match the app-side transaction builder.

## References
1. Joux, A. (2000). A One Round Protocol for Tripartite Diffie–Hellman. In: Bosma, W. (eds) Algorithmic Number Theory. ANTS 2000. Lecture Notes in Computer Science, vol 1838. Springer, Berlin, Heidelberg. https://doi.org/10.1007/10722028_23
38 changes: 38 additions & 0 deletions ape-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: Secret-Escrow

plugins:
- name: solidity
- name: foundry

dependencies:
- name: OpenZeppelin
github: OpenZeppelin/openzeppelin-contracts
version: 4.9.3

compile:
include_dependencies: true

solidity:
version: 0.8.34
evm_version: berlin
import_remapping:
- OpenZeppelin/openzeppelin-contracts@4.9.3=@openzeppelin

ethereum:
default_network: local

local:
default_provider: foundry

foundry:
host: http://127.0.0.1:8545
base_fee: 0
priority_fee: 0
evm_version: berlin
request_timeout: 60
process_attempts: 10

test:
mnemonic: test test test test test test test test test test test junk
number_of_accounts: 10
hd_path: m/44'/60'/0'/0/{}
24 changes: 17 additions & 7 deletions app/utils/contract_utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import json
from pathlib import Path
from typing import Tuple, Type, TypeVar

from eth_utils import to_checksum_address
from eth_utils.address import to_checksum_address
from web3.contract import Contract
from web3.exceptions import (
ABIFunctionNotFound,
Expand All @@ -15,19 +16,26 @@
from config import CHAIN_ID, TX_GAS_LIMIT

web3 = Web3Wrapper()
OUTPUT_DIR = Path("output")


class ContractUtils:
factory_map: dict[str, Type[Contract]] = {}

@staticmethod
def _get_contract_path(contract_name: str) -> Path:
return OUTPUT_DIR / f"{contract_name}.json"

@staticmethod
def get_contract_code(contract_name: str):
"""Get contract code

:param contract_name: contract name
:return: ABI, bytecode, deployedBytecode
"""
contract_json = json.load(open(f"build/contracts/{contract_name}.json", "r"))
contract_path = ContractUtils._get_contract_path(contract_name)
with contract_path.open("r", encoding="utf-8") as file:
contract_json = json.load(file)

if "bytecode" not in contract_json.keys():
contract_json["bytecode"] = None
Expand All @@ -51,9 +59,10 @@ def deploy_contract(
:param private_key: private key
:return: contract address, ABI, transaction hash
"""
contract_file = f"contracts/{contract_name}.json"
try:
contract_json = json.load(open(contract_file, "r"))
contract_path = ContractUtils._get_contract_path(contract_name)
with contract_path.open("r", encoding="utf-8") as file:
contract_json = json.load(file)
except FileNotFoundError as file_not_found_err:
raise SendTransactionError(file_not_found_err)

Expand Down Expand Up @@ -103,8 +112,9 @@ def get_contract(cls, contract_name: str, contract_address: str):
if contract_factory is not None:
return contract_factory(address=to_checksum_address(contract_address))

contract_file = f"build/contracts/{contract_name}.json"
contract_json = json.load(open(contract_file, "r"))
contract_path = cls._get_contract_path(contract_name)
with contract_path.open("r", encoding="utf-8") as file:
contract_json = json.load(file)
contract_factory = web3.eth.contract(abi=contract_json["abi"])
cls.factory_map[contract_name] = contract_factory
return contract_factory(address=to_checksum_address(contract_address))
Expand Down Expand Up @@ -150,7 +160,7 @@ def send_transaction(transaction: dict, private_key: str):
transaction_dict=transaction, private_key=private_key
)
# Send Transaction
tx_hash = web3.eth.send_raw_transaction(signed_tx.rawTransaction.hex())
tx_hash = web3.eth.send_raw_transaction(signed_tx.raw_transaction.hex())
tx_receipt = web3.eth.wait_for_transaction_receipt(
transaction_hash=tx_hash, timeout=10
)
Expand Down
4 changes: 2 additions & 2 deletions app/utils/web3_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

from eth_typing import URI
from web3 import Web3
from web3.middleware import geth_poa_middleware
from web3.middleware import ExtraDataToPOAMiddleware
from web3.types import RPCEndpoint, RPCResponse

from config import WEB3_HTTP_PROVIDER
Expand Down Expand Up @@ -39,7 +39,7 @@ def _get_web3() -> Web3:
web3 = thread_local.web3
except AttributeError:
web3 = Web3(FailOverHTTPProvider())
web3.middleware_onion.inject(geth_poa_middleware, layer=0)
web3.middleware_onion.inject(ExtraDataToPOAMiddleware, layer=0)
thread_local.web3 = web3

return web3
Expand Down
13 changes: 0 additions & 13 deletions brownie-config.yaml

This file was deleted.

2 changes: 1 addition & 1 deletion contracts/exchange/IbetSecurityTokenDVP.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
pragma solidity ^0.8.34;

import "OpenZeppelin/openzeppelin-contracts@4.9.3/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "./DVPStorage.sol";
import "../access/Ownable.sol";
import "../utils/Errors.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/token/IbetShare.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
pragma solidity ^0.8.34;

import "OpenZeppelin/openzeppelin-contracts@4.9.3/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../access/Ownable.sol";
import "../ledger/PersonalInfo.sol";
import "../utils/Errors.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/token/IbetStandardToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

pragma solidity ^0.8.34;

import "OpenZeppelin/openzeppelin-contracts@4.9.3/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../access/Ownable.sol";
import "../utils/Errors.sol";
import "../../interfaces/ContractReceiver.sol";
Expand Down
2 changes: 1 addition & 1 deletion contracts/token/IbetStraightBond.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
pragma solidity ^0.8.34;

import "OpenZeppelin/openzeppelin-contracts@4.9.3/contracts/utils/math/SafeMath.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import "../access/Ownable.sol";
import "../ledger/PersonalInfo.sol";
import "../utils/Errors.sol";
Expand Down
7 changes: 0 additions & 7 deletions data/networks.yml

This file was deleted.

12 changes: 6 additions & 6 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 8 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ authors = [
license = {text = "Apache License, Version 2.0"}
requires-python = "==3.11.12"
dependencies = [
"py-ecc~=7.0.0",
"ape-foundry~=0.8.12",
"ape-solidity~=0.8.5",
"eth-ape~=0.8.49",
"py-ecc>=8.0.0,<9",
"pycryptodome~=3.20",
"web3~=6.15.1",
"web3>=6.20.1,<8",
"coincurve~=19.0.1",
"eth-brownie~=1.20.3",
"pydantic~=2.7.1",
"pydantic>=2.10,<3",
]
name = "Secret-Escrow"
version = "0.0.1"
Expand All @@ -26,7 +28,8 @@ dev = [
exclude-newer = "7 days"

[tool.pytest.ini_options]
addopts = ["--network=test_network"]
addopts = ["--network=ethereum:local:foundry"]
pythonpath = ["."]

[tool.ruff]
line-length = 88
Expand Down
Empty file added scripts/.gitkeep
Empty file.
Loading
Loading