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

feat: Secret contract deploys #17

Merged
merged 2 commits into from
Oct 15, 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
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -255,15 +255,15 @@ echo 'export CC=/opt/homebrew/opt/llvm/bin/clang' >> ~/.zshrc
source ~/.zshrc
```

* Compile. Note: Outputs contract.wasm and contract.wasm.gz file in the root directory of the secret-contracts/nunya-contract folder
* Run Docker (e.g. Docker Desktop on macOS)

* [Compile](https://docs.scrt.network/secret-network-documentation/development/readme-1/compile-and-deploy#compile-the-code). Note: Outputs contract.wasm and contract.wasm.gz file in the root directory of the secret-contracts/nunya-contract folder. Using `make build-mainnet-reproducible` will remove contract.wasm so only the optimised contract.wasm.gz remains. Warning: If you only run `make build-mainnet` then you will get this error https://github.com/svub/nunya/issues/8 when deploying.

```
cd packages/secret-contracts/nunya-contract
make build
make build-mainnet-reproducible
```

* OPTIONAL - optimize contract code. Refer to official Secret network docs

* Upload and Instantiate

> IMPORTANT: Currently unable to deploy due to this TNLS error https://github.com/svub/nunya/issues/8
Expand All @@ -272,6 +272,10 @@ make build
yarn run secret:clean:uploadContract
yarn run secret:start:uploadContract
```
* Query Pubkey
```
yarn run secret:queryPubkey
```
* View logs at ./logs/instantiateOutput.log
* View on Secret Testnet block explorer at https://testnet.ping.pub/secret/

Expand Down
20 changes: 20 additions & 0 deletions docker/secret-contract-optimizer.Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# https://github.com/scrtlabs/SecretNetwork/blob/master/deployment/dockerfiles/base-images/secret-contract-optimizer.Dockerfile#L9
# v1.0.10
# Modifications:
# - removed `--locked`
# - added `--enable-threads --enable-bulk-memory --all-features`
FROM rust:1.71.0-slim-bullseye

RUN rustup target add wasm32-unknown-unknown
RUN apt update && apt install -y binaryen clang && rm -rf /var/lib/apt/lists/*

WORKDIR /contract

ENTRYPOINT ["/bin/bash", "-c", "\
RUSTFLAGS='-C link-arg=-s' cargo build --release --lib --target wasm32-unknown-unknown && \
(mkdir -p ./optimized-wasm/ && rm -f ./optimized-wasm/* && cp ./target/wasm32-unknown-unknown/release/*.wasm ./optimized-wasm/) && \
for w in ./optimized-wasm/*.wasm; do \
wasm-opt -Oz $w -o $w --enable-threads --enable-bulk-memory --all-features; \
done && \
(cd ./optimized-wasm && gzip -n -9 -f *) \
"]
33 changes: 17 additions & 16 deletions logs/instantiateOutput.log
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
Starting deployment...
codeId: 10593
CODE_HASH: 5ea3b37c0f3b06a621e58327bd7235fd8c323a4a595b095914c5fd2a5511dc93
tx.rawLog: [{"events":[{"type":"message","attributes":[{"key":"action","value":"/secret.compute.v1beta1.MsgStoreCode"},{"key":"module","value":"compute"},{"key":"sender","value":"secret1am2mk908456twwgehmaua85s6laar4yr3awzzj"},{"key":"signer","value":"secret1am2mk908456twwgehmaua85s6laar4yr3awzzj"},{"key":"code_id","value":"11036"}]}]}]
codeId: 11036
CODE_HASH: 1af180cc6506af23fb3ee2c0f6ece37ab3ad32db82e061b6b30679fb8a3f1323
params: {
codeId: '10593',
contractCodeHash: '5ea3b37c0f3b06a621e58327bd7235fd8c323a4a595b095914c5fd2a5511dc93'
codeId: '11036',
contractCodeHash: '1af180cc6506af23fb3ee2c0f6ece37ab3ad32db82e061b6b30679fb8a3f1323'
}
Instantiating contract...
tx: {
height: 7098192,
timestamp: '',
transactionHash: 'C5419257F2ED564093D27F1B73F4EAC4EAABC950EBE590C6B7C9C7B9CC434DEC',
height: 7247704,
timestamp: '2024-10-15T20:20:28Z',
transactionHash: '7575955CBA2BFA353C96E5F58767A07DC35FEEDEBA92BD8847D4391F0F8F0DF6',
code: 0,
codespace: '',
info: '',
Expand All @@ -24,19 +25,19 @@ tx: {
},
auth_info: { signer_infos: [Array], fee: [Object] },
signatures: [
'J1Ei+KHikPOXjRfuP1b22UYlxdHJM6TpntR8KFmAEmBPRW2CFou8WFO9Nubg/vAR/bC0cKybR7d9+Rkb77rjNQ=='
'BwgEzvF5mUkZALqvFQwb+SxuBGWJwbJQoGCbdvys2FlQ10LtkIc0xJwQTpiSszYCjluE/+nHVX6kzWBiICMpOQ=='
]
},
rawLog: '[{"events":[{"type":"instantiate","attributes":[{"key":"contract_address","value":"secret19kk5wcmxp2alr356emljyr8xp90atndxy3r2c9"},{"key":"code_id","value":"10593"}]},{"type":"message","attributes":[{"key":"action","value":"/secret.compute.v1beta1.MsgInstantiateContract"},{"key":"module","value":"compute"},{"key":"sender","value":"secret1am2mk908456twwgehmaua85s6laar4yr3awzzj"},{"key":"contract_address","value":"secret19kk5wcmxp2alr356emljyr8xp90atndxy3r2c9"}]},{"type":"wasm","attributes":[{"key":"contract_address","value":"secret19kk5wcmxp2alr356emljyr8xp90atndxy3r2c9"}]}]}]',
rawLog: '[{"events":[{"type":"instantiate","attributes":[{"key":"contract_address","value":"secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3"},{"key":"code_id","value":"11036"}]},{"type":"message","attributes":[{"key":"action","value":"/secret.compute.v1beta1.MsgInstantiateContract"},{"key":"module","value":"compute"},{"key":"sender","value":"secret1am2mk908456twwgehmaua85s6laar4yr3awzzj"},{"key":"contract_address","value":"secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3"}]},{"type":"wasm","attributes":[{"key":"contract_address","value":"secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3"}]}]}]',
jsonLog: [ { events: [Array], msg_index: 0 } ],
arrayLog: [
{
msg: 0,
type: 'instantiate',
key: 'contract_address',
value: 'secret19kk5wcmxp2alr356emljyr8xp90atndxy3r2c9'
value: 'secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3'
},
{ msg: 0, type: 'instantiate', key: 'code_id', value: '10593' },
{ msg: 0, type: 'instantiate', key: 'code_id', value: '11036' },
{
msg: 0,
type: 'message',
Expand All @@ -54,13 +55,13 @@ tx: {
msg: 0,
type: 'message',
key: 'contract_address',
value: 'secret19kk5wcmxp2alr356emljyr8xp90atndxy3r2c9'
value: 'secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3'
},
{
msg: 0,
type: 'wasm',
key: 'contract_address',
value: 'secret19kk5wcmxp2alr356emljyr8xp90atndxy3r2c9'
value: 'secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3'
}
],
events: [
Expand All @@ -77,10 +78,10 @@ tx: {
{ type: 'message', attributes: [Array] }
],
data: [
<Buffer 0a 2d 73 65 63 72 65 74 31 39 6b 6b 35 77 63 6d 78 70 32 61 6c 72 33 35 36 65 6d 6c 6a 79 72 38 78 70 39 30 61 74 6e 64 78 79 33 72 32 63 39>
<Buffer 0a 2d 73 65 63 72 65 74 31 75 77 71 64 6a 6e 7a 72 74 74 65 70 6e 38 36 70 32 73 6a 6d 6e 75 67 66 70 68 37 74 7a 39 37 68 6d 63 77 6a 73 33>
],
gasUsed: 43476,
gasUsed: 45183,
gasWanted: 400000,
ibcResponses: []
}
SECRET_ADDRESS: secret19kk5wcmxp2alr356emljyr8xp90atndxy3r2c9
SECRET_ADDRESS: secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"vercel": "yarn workspace @se-2/nextjs vercel",
"vercel:yolo": "yarn workspace @se-2/nextjs vercel:yolo",
"verify": "yarn workspace @se-2/hardhat verify",
"secret:queryPubkey": "yarn workspace secret-upload-contract queryPubkey",
"secret:clean:uploadContract": "yarn workspace secret-upload-contract clean",
"secret:start:uploadContract": "yarn workspace secret-upload-contract start",
"secret:clean:instantiateContract": "yarn workspace secret-instantiate-contract clean",
Expand Down
1 change: 1 addition & 0 deletions packages/hardhat/contracts/NunyaBusiness.sol
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ contract NunyaBusiness {
// TODO: only uncomment when hardhat has gateway deployed
// TODO can we test if it's deployed and call then automatically?
// IDEA use requestId to make sure nobody else is calling the callback, see below.
// Note: It may be necessary to call using snake case.
// const requestId = secretContract.retrievePubkey();
// expectedResult[requestId] = FunctionCallType.GET_KEY;

Expand Down
4 changes: 3 additions & 1 deletion packages/secret-contracts/nunya-contract/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ yarn-error.log*
contract.wasm
contract.wasm.gz

/target
/optimized-wasm

/target
26 changes: 22 additions & 4 deletions packages/secret-contracts/nunya-contract/Cargo.lock

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

12 changes: 8 additions & 4 deletions packages/secret-contracts/nunya-contract/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,16 @@ _build-mainnet:
cargo clean && AR=/opt/homebrew/opt/llvm/bin/llvm-ar CC=/opt/homebrew/opt/llvm/bin/clang RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown

# like build-mainnet, but slower and more deterministic
# https://hub.docker.com/r/enigmampc/secret-contract-optimizer/tags
.PHONY: build-mainnet-reproducible
build-mainnet-reproducible:
docker run --rm -v "$$(pwd)":/contract \
--mount type=volume,source="$$(basename "$$(pwd)")_cache",target=/contract/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
ghcr.io/scrtlabs/localsecret:v1.6.0-rc.3
cargo clean && AR=/opt/homebrew/opt/llvm/bin/llvm-ar CC=/opt/homebrew/opt/llvm/bin/clang RUSTFLAGS='-C link-arg=-s' && \
docker rmi sco && \
docker buildx build --label "sco" --tag "sco" -f "../../../docker/secret-contract-optimizer.Dockerfile" . && \
docker run --rm -v "$$(pwd)":/contract \
--mount type=volume,source="$$(basename "$$(pwd)")_cache",target=/contract/target \
--mount type=volume,source=registry_cache,target=/usr/local/cargo/registry \
sco:latest

.PHONY: compress-wasm
compress-wasm:
Expand Down
5 changes: 5 additions & 0 deletions packages/secret-contracts/nunya-contract/cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ tnls = { git = "https://github.com/SecretSaturn/TNLS", branch = "main", package
# cw-storage-plus = { version = "0.14.0", default-features = false }
anybuf = {version = "0.5.0"}

# crypto
hex = "0.4.3"
# secp256k1 = { version = "0.17.2", default-features = false }
secp256k1 = { git = "https://github.com/scrtlabs/rust-secp256k1" }

[[bin]]
name = "schema"
required-features = ["schema"]
39 changes: 37 additions & 2 deletions packages/secret-contracts/nunya-contract/src/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
},
state::{
PaymentReceipt, PaymentReferenceBalance, ResponseStatusCode,
State, CONFIG, MY_KEYS,
MyKeys, State, CONFIG, MY_KEYS,
VIEWING_KEY, VIEWING_KEY_TO_PAYMENT_REF_TO_BALANCES_MAP,
},
};
Expand All @@ -19,17 +19,45 @@ use tnls::{
msg::{PostExecutionMsg, PrivContractHandleMsg},
state::Task,
};
use secp256k1::{PublicKey, Secp256k1, SecretKey};

use anybuf::Anybuf;

/// pad handle responses and log attributes to blocks of 256 bytes to prevent leaking info based on
/// response size
pub const BLOCK_SIZE: usize = 256;

// Create Secret Contract Keys
// TODO: use ContractError instead of StdError
// pub fn try_create_keys(deps: DepsMut, env: Env) -> Result<Response, ContractError> {
pub fn try_create_keys(deps: DepsMut, env: Env) -> StdResult<Response> {
let rng = env.block.random.unwrap().0;
let secp = Secp256k1::new();

// Private Key
let private_key = SecretKey::from_slice(&rng).unwrap();
let private_key_string = private_key.to_string();
let private_key_bytes = hex::decode(private_key_string).unwrap();

// Public Key
let public_key = PublicKey::from_secret_key(&secp, &private_key);
let public_key_bytes = public_key.serialize().to_vec();
// let public_key_string = public_key.to_string();

let my_keys = MyKeys {
private_key: private_key_bytes,
public_key: public_key_bytes,
};

MY_KEYS.save(deps.storage, &my_keys)?;

Ok(Response::default())
}

#[entry_point]
pub fn instantiate(
deps: DepsMut,
_env: Env,
env: Env,
_info: MessageInfo,
msg: InstantiateMsg,
) -> StdResult<Response> {
Expand All @@ -42,6 +70,8 @@ pub fn instantiate(

CONFIG.save(deps.storage, &state)?;

try_create_keys(deps, env)?;

Ok(Response::default())
}

Expand All @@ -63,6 +93,10 @@ fn try_handle(
// verify signature with stored gateway public key
let config = CONFIG.load(deps.storage)?;

// SecretPath source code
// public network user address
let user_address = msg.user_address;

// Security
//
// reference: evm-kv-store-demo
Expand Down Expand Up @@ -309,6 +343,7 @@ fn create_pay(
let input: PayStoreMsg = serde_json_wasm::from_str(&input_values)
.map_err(|err| StdError::generic_err(err.to_string()))?;

// TODO: validate the input.secret_user input
let viewing_key_index = input.secret_user.as_str(); // convert u8 to String
let payment_ref = input.payment_ref.as_str(); // convert Uint256 to String
// TODO: handle error if issue with amount or denomination received
Expand Down
1 change: 1 addition & 0 deletions packages/secret-upload-contract/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"main": "index.js",
"private": true,
"scripts": {
"queryPubkey": "yarn build && node ./dist/queryPubkey.js",
"build": "./node_modules/.bin/tsc --build",
"clean": "./node_modules/.bin/tsc --build --clean",
"start": "yarn build && node ./dist/index.js"
Expand Down
2 changes: 1 addition & 1 deletion packages/secret-upload-contract/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ async function main () {
const query_tx = await secretjs.query.compute.queryContract({
contract_address: params?.contractAddress?.toString(),
code_hash: params?.contractCodeHash?.toString(),
query: { retrieve_pubkey_query: { key: 1 } },
query: { retrieve_pubkey: {} },
});
console.log(query_tx);
}
Expand Down
42 changes: 42 additions & 0 deletions packages/secret-upload-contract/src/queryPubkey.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { SecretNetworkClient } from "secretjs";

// Replace with deployed Secret contract details
const SECRET_ADDRESS = "secret1uwqdjnzrttepn86p2sjmnugfph7tz97hmcwjs3"
const CODE_HASH = "1af180cc6506af23fb3ee2c0f6ece37ab3ad32db82e061b6b30679fb8a3f1323"

let query_pubkey = async (secretjs, params) => {
const query_tx = await secretjs.query.compute.queryContract({
contract_address: params.contractAddress,
code_hash: params.contractCodeHash,
query: { retrieve_pubkey: {} },
});
console.log(query_tx);
return query_tx;
}

async function main() {
let contractParams = {
contractAddress: SECRET_ADDRESS,
contractCodeHash: CODE_HASH,
};

const secretjs = new SecretNetworkClient({
url: "https://lcd.testnet.secretsaturn.net",
chainId: "pulsar-3",
});

// Chain the execution using promises
await query_pubkey(secretjs, contractParams)
.then(async (res) => {
console.log('res: ', res);
})
.catch((error) => {
console.error("Error:", error);
});

process.exit()
}
main().catch((error) => {
console.error(error);
process.exit(-1);
});
Loading