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

docs: Migrate Precompiles chapter to inline .sol API docs #243

Merged
merged 2 commits into from
Jan 23, 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
10 changes: 4 additions & 6 deletions .github/workflows/ci-docs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,11 @@ jobs:
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1

- name: Install forge doc deps
run: cargo install mdbook-pagetoc

- name: Build docs
run: |
forge doc --build
# Inject another /contracts/ for github.com URLs.
find sol/sapphire-contracts/book -name *.html | xargs sed -i -E "s+(blob/.*/contracts)+\1/contracts+"
# Remove /src/ from "Inherits" links.
find sol/sapphire-contracts/book -name *.html | xargs sed -i "s+/src/+/+"
run: pnpm doc

- name: Deploy to api-reference branch
uses: peaceiris/actions-gh-pages@v3
Expand Down
5 changes: 3 additions & 2 deletions .github/workflows/contracts-test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ jobs:
${{ runner.os }}-pnpm-store-
- name: Install Foundry
uses: foundry-rs/foundry-toolchain@v1
- name: Install forge doc deps
run: cargo install mdbook-pagetoc
- name: Install dependencies
run: pnpm install
- name: Build JS client
Expand All @@ -69,8 +71,7 @@ jobs:
run: pnpm hardhat test --network sapphire-localnet-ci
- name: Build docs
working-directory: contracts
run: |
forge doc --build
run: pnpm doc
- name: hardhat test examples/hardhat
working-directory: examples/hardhat
run: pnpm hardhat run --network sapphire-localnet scripts/run-vigil.ts
Expand Down
1 change: 1 addition & 0 deletions contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ coverage.json
coverage/
gasReporterOutput.json
typechain-types/
sol/
26 changes: 23 additions & 3 deletions contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,38 @@ $ pnpm install @oasisprotocol/sapphire-contracts

#### Usage

Once installed, you can import Sapphire contracts.
Once installed, you can import and use the Sapphire contracts as follows:

```solidity
import {Enclave} from "@oasisprotocol/sapphire-contracts/contracts/OPL.sol";
pragma solidity ^0.8.13;

import "@oasisprotocol/sapphire-contracts/contracts/Sapphire.sol";

contract RandomNumber {
function generateNumber() public view returns (uint) {
return uint(bytes32(Sapphire.randomBytes(32, "")));
}
}
```

## Documentation

See the user's guide for [Sapphire](https://docs.oasis.io/dapp/sapphire/) and
[OPL](https://docs.oasis.io/dapp/opl/).

API reference is available at [api.docs.oasis.io](https://docs.oasis.io/sol/sapphire-contracts).
The generated API reference is hosted at
[api.docs.oasis.io](https://api.docs.oasis.io/sol/sapphire-contracts).

Generating API docs locally requires Foundry and mdbook-pagetoc. To install
them and generate the docs execute:

```shell
curl -L https://foundry.paradigm.xyz | bash
cargo install mdbook-pagetoc
pnpm doc
```

The API docs index will be located in `sol/sapphire-contracts/book/index.html`.

## Contribute

Expand Down
4 changes: 4 additions & 0 deletions contracts/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[preprocessor.pagetoc]
[output.html]
additional-css = ["theme/pagetoc.css"]
additional-js = ["theme/pagetoc.js"]
29 changes: 16 additions & 13 deletions contracts/contracts/ConsensusUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,23 @@ type StakingSecretKey is bytes32;

/**
* @title Consensus-level utilities
* @dev Generate Oasis wallets for use with staking at the consensus level
* @notice Generate Oasis wallets for use with staking at the consensus level.
*/
library ConsensusUtils {
/// The unique context for v0 staking account addresses.
/// https://github.com/oasisprotocol/oasis-core/blob/master/go/staking/api/address.go#L16
/**
* @notice The unique context for v0 staking account addresses.
* @custom:see @oasisprotocol/oasis-core :: go/staking/api/address.go
*/
string private constant ADDRESS_V0_CONTEXT_IDENTIFIER =
"oasis-core/address: staking";
uint8 private constant ADDRESS_V0_CONTEXT_VERSION = 0;

/**
* @dev Generate a random Ed25519 wallet for Oasis consensus-layer staking
* @param personalization Optional user-specified entropy
* @return publicAddress Public address of the keypair
* @return secretKey Secret key for the keypair
* @notice Generate a random Ed25519 wallet for Oasis consensus-layer
* staking.
* @param personalization Optional user-specified entropy.
* @return publicAddress Public address of the keypair.
* @return secretKey Secret key for the keypair.
*/
function generateStakingAddress(bytes memory personalization)
internal
Expand All @@ -47,8 +50,8 @@ library ConsensusUtils {
}

/**
* @dev Derive the staking address from the public key
* @param ed25519publicKey Ed25519 public key
* @notice Derive the staking address from the public key.
* @param ed25519publicKey Ed25519 public key.
*/
function _stakingAddressFromPublicKey(bytes32 ed25519publicKey)
internal
Expand All @@ -64,10 +67,10 @@ library ConsensusUtils {
}

/**
* @dev Derive an Oasis-style address
* @param contextIdentifier Domain separator
* @param contextVersion Domain version
* @param data Public point of the keypair
* @notice Derive an Oasis-style address.
* @param contextIdentifier Domain separator.
* @param contextVersion Domain version.
* @param data Public point of the keypair.
*/
function _addressFromData(
string memory contextIdentifier,
Expand Down
23 changes: 12 additions & 11 deletions contracts/contracts/EIP155Signer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@ library EIP155Signer {
}

/**
* Encode a signed EIP-155 transaction
* @param rawTx Transaction which was signed
* @param rsv R, S & V parameters of signature
* @notice Encode a signed EIP-155 transaction.
* @param rawTx Transaction which was signed.
* @param rsv R, S & V parameters of signature.
*/
function encodeSignedTx(EthTx memory rawTx, SignatureRSV memory rsv)
internal
Expand All @@ -43,10 +43,11 @@ library EIP155Signer {
}

/**
* Sign a raw transaction, which will then need to be encoded to include the signature
* @param rawTx Transaction to sign
* @param pubkeyAddr Ethereum address of secret key
* @param secretKey Secret key used to sign
* @notice Sign a raw transaction, which will then need to be encoded to
* include the signature.
* @param rawTx Transaction to sign.
* @param pubkeyAddr Ethereum address of secret key.
* @param secretKey Secret key used to sign.
*/
function signRawTx(
EthTx memory rawTx,
Expand All @@ -64,10 +65,10 @@ library EIP155Signer {
}

/**
* Sign a transaction, returning it in EIP-155 encoded form
* @param publicAddress Ethereum address of secret key
* @param secretKey Secret key used to sign
* @param transaction Transaction to sign
* @notice Sign a transaction, returning it in EIP-155 encoded form.
* @param publicAddress Ethereum address of secret key.
* @param secretKey Secret key used to sign.
* @param transaction Transaction to sign.
*/
function sign(
address publicAddress,
Expand Down
62 changes: 35 additions & 27 deletions contracts/contracts/EthereumUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ library EthereumUtils {
error k256DeriveY_Invalid_Prefix_Error();

/**
* Recover Y coordinate from X coordinate and sign bit
* @param prefix 0x02 or 0x03 indicates sign bit of compressed point
* @param x X coordinate
* @notice Recover Y coordinate from X coordinate and sign bit.
* @param prefix 0x02 or 0x03 indicates sign bit of compressed point.
* @param x X coordinate.
*/
function k256DeriveY(uint8 prefix, uint256 x)
internal
Expand All @@ -73,10 +73,10 @@ library EthereumUtils {
error k256Decompress_Invalid_Length_Error();

/**
* Decompress SEC P256 k1 point
* @param pk 33 byte compressed public key
* @return x coordinate
* @return y coordinate
* @notice Decompress SEC P256 k1 point.
* @param pk 33 byte compressed public key.
* @return x X coordinate.
* @return y Y coordinate.
*/
function k256Decompress(bytes memory pk)
internal
Expand All @@ -101,10 +101,10 @@ library EthereumUtils {
}

/**
* Convert SEC P256 k1 curve point to Ethereum address
* @param x coordinate
* @param y coordinate
* @custom:see https://gavwood.com/paper.pdf (212)
* @notice Convert SEC P256 k1 curve point to Ethereum address.
* @param x X coordinate.
* @param y Y coordinate.
* @custom:see https://gavwood.com/paper.pdf (pp. 212)
*/
function toEthereumAddress(uint256 x, uint256 y)
internal
Expand All @@ -119,17 +119,22 @@ library EthereumUtils {
error DER_Split_Error();

/**
* Extracts the `r` and `s` parameters from a DER encoded ECDSA signature.
* @notice Extracts the `r` and `s` parameters from a DER encoded ECDSA
* signature.
*
* The signature is an ASN1 encoded SEQUENCE of the variable length `r` and `s` INTEGERs.
* The signature is an ASN1 encoded SEQUENCE of the variable length `r` and
* `s` INTEGERs.
*
* ```
* | 0x30 | len(z) | 0x02 | len(r) | r | 0x02 | len(s) | s | = hex value
* | 1 | 1 | 1 | 1 | 1-33 | 1 | 1 | 1-33 | = byte length
* ```
*
* If the highest bit of either `r` or `s` is set, it will be prefix padded with a zero byte
* There is exponentially decreasing probability that either `r` or `s` will be below 32 bytes.
* There is a very high probability that either `r` or `s` will be 33 bytes.
* This function only works if either `r` or `s` are 256bits or lower.
* If the highest bit of either `r` or `s` is set, it will be prefix padded
* with a zero byte. There is exponentially decreasing probability that
* either `r` or `s` will be below 32 bytes. There is a very high
* probability that either `r` or `s` will be 33 bytes. This function only
* works if either `r` or `s` are 256bits or lower.
*
* @param der DER encoded ECDSA signature
* @return rsv ECDSA R point X coordinate, and S scalar
Expand Down Expand Up @@ -214,13 +219,15 @@ library EthereumUtils {
}

/**
* Convert a Secp256k1PrehashedKeccak256 signature to one accepted by ecrecover
* @param pubkey 33 byte compressed public key
* @param digest 32 byte pre-hashed message digest
* @param signature ASN.1 DER encoded signature, as returned from `Sapphire.sign`
* @return pubkeyAddr 20 byte Ethereum address
* @return rsv Ethereum EcDSA RSV signature values
* @custom:see https://gavwood.com/paper.pdf (206)
* @notice Convert a Secp256k1PrehashedKeccak256 signature to one accepted
* by ecrecover.
* @param pubkey 33 byte compressed public key.
* @param digest 32 byte pre-hashed message digest.
* @param signature ASN.1 DER encoded signature, as returned from
* [`Sapphire.sign`](../Sapphire.sol/library.Sapphire.md#sign).
* @return pubkeyAddr 20 byte Ethereum address.
* @return rsv Ethereum EcDSA RSV signature values.
* @custom:see https://gavwood.com/paper.pdf (pp. 206)
*/
function toEthereumSignature(
bytes memory pubkey,
Expand Down Expand Up @@ -252,9 +259,10 @@ library EthereumUtils {
}

/**
* Generates an Ethereum compatible SEC P256 k1 keypair and corresponding public address
* @return pubkeyAddr Ethereum address
* @return secretKey Secret key used for signing
* @notice Generate an Ethereum compatible SEC P256 k1 keypair and
* corresponding public address.
* @return pubkeyAddr Ethereum address.
* @return secretKey Secret key used for signing.
*/
function generateKeypair()
internal
Expand Down
Loading
Loading