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

Add chain signatures article ("what it is") #1704

Merged
merged 32 commits into from
Feb 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ee7f1b9
add chain signatures
bucanero Feb 1, 2024
ccee6eb
Merge branch 'master' into 1678-doc-create-chain-signatures-what-it-i…
bucanero Feb 1, 2024
64b1961
Update docs/1.concepts/account-abstraction/chainsig.md
bucanero Feb 2, 2024
f9ac471
Update docs/1.concepts/account-abstraction/chainsig.md
bucanero Feb 2, 2024
d4d8a62
Update docs/1.concepts/account-abstraction/chainsig.md
bucanero Feb 2, 2024
da8b61c
Update chainsig.md
bucanero Feb 2, 2024
db34bc5
Update chainsig.md
bucanero Feb 8, 2024
3712758
Merge branch 'master' into 1678-doc-create-chain-signatures-what-it-i…
bucanero Feb 8, 2024
75f9d45
Update chainsig.md
bucanero Feb 12, 2024
720c527
Merge branch 'master' into 1678-doc-create-chain-signatures-what-it-i…
bucanero Feb 12, 2024
696e382
Merge branch 'master' into 1678-doc-create-chain-signatures-what-it-i…
bucanero Feb 16, 2024
924bbeb
minor changes
gagdiez Feb 16, 2024
ceea159
Merge branch 'abstractions' into 1678-doc-create-chain-signatures-wha…
gagdiez Feb 16, 2024
b6c1100
Merge branch '1678-doc-create-chain-signatures-what-it-is-article' of…
gagdiez Feb 16, 2024
dc89894
update
bucanero Feb 16, 2024
30c7105
add trade use-case
bucanero Feb 17, 2024
08d74ba
Merge branch 'master' into 1678-doc-create-chain-signatures-what-it-i…
bucanero Feb 17, 2024
3d0de21
re-worked text
gagdiez Feb 20, 2024
f6d53a1
merge
gagdiez Feb 20, 2024
bada37e
Update docs/1.concepts/abstraction/relayers.md
bucanero Feb 20, 2024
9c821f6
Merge branch 'master' into 1678-doc-create-chain-signatures-what-it-i…
bucanero Feb 20, 2024
0dc2057
update high level what-is
thisisjoshford Feb 21, 2024
ff8a64b
update how it works & create payload
thisisjoshford Feb 21, 2024
0a34cbb
update what-is intro
thisisjoshford Feb 21, 2024
e8b9b76
update signature request
thisisjoshford Feb 21, 2024
478361a
minor copy edits & .vscode ignore
thisisjoshford Feb 21, 2024
ef8a5bc
Merge branch 'master' into 1678-doc-create-chain-signatures-what-it-i…
bucanero Feb 22, 2024
844b004
links
bucanero Feb 22, 2024
3554188
minor edits
gagdiez Feb 22, 2024
843720e
add defi on bitcoin usecase per Kendall
thisisjoshford Feb 22, 2024
645b5fe
added build chain signature
gagdiez Feb 23, 2024
8d58375
Merge branch '1678-doc-create-chain-signatures-what-it-is-article' of…
gagdiez Feb 23, 2024
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ neardev
.idea
.docz
serve*

.vscode
110 changes: 110 additions & 0 deletions docs/1.concepts/abstraction/chain-signatures.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
id: chain-signatures
title: Chain Signatures
sidebar_label: What are Chain Signatures?
---

Chain Signatures unlock the ability for a single account to transact across multiple blockchain protocols, giving ownership of cross-chain accounts, data, and assets to one NEAR account.

This many-to-one ownership is made possible through a mixture of services across our tech stack:

1. A [smart contract](../basics/accounts/smartcontract.md) that holds requests for multi-chain signatures.
2. A [multiparty computation](https://www.zellic.io/blog/mpc-from-scratch/) service listening for signature requests.
3. A multi-chain [relayer](./relayers.md), which can submit signed transactions to other networks.

:::info
This section presents an overview of Chain Signatures. To create one, please switch to the [**building a Chain Signature**](../../8.abstraction/chain-signatures.md) document.
:::

---

## How It Works

![chain-signatures](/docs/assets/welcome-pages/chain-signatures-overview.png)
_Diagram of a chain signature in NEAR_

There are four steps involved on Chain Signatures:

1. [Create a Payload](#1-create-a-payload) - The user creates the transaction / message they want to sign
2. [Signature Request](#2-request-signature) - The user calls the NEAR `multichain` contract, requesting to sign the transaction
3. [MPC Signing Service](#3-sign-with-mpc) - A service captures the call, and returns the signed the transaction for the user
4. [Relay Signed Payload](#4-relaying-the-signature) - The signed payload is then sent to the destination chain for execution.

<hr class="subsection" />

### 1. Create Payload

The first step is to construct a payload (transaction, message, data, etc.) for the target blockchain platform. This variates depending on the target blockchain, but in general, it's a hash of the message or transaction to be signed.

<hr class="subsection" />

### 2. Signature Request

Once a payload is created and ready to sign, a signature request is made by calling `sign` on the deployed smart contract `multichain.near`. This method takes two parameters:
1. **payload:** The payload (transaction, message, data, etc.) to be signed for the target blockchain
2. **path:** A name representing the account that should be used to sign the payload (e.g. ethereum-1)

```rust
pub fn sign(payload: [u8; 32], path: String) -> Signature
```
_[See the full code in Github](https://github.com/near/mpc-recovery/blob/bc85d66833ffa8537ec61d0b22cd5aa96fbe3197/contract/src/lib.rs#L263)_

For example, a user could request a signature to `send 0.1 ETH to 0x060f1...` **(payload)** using the `ethereum-1` account **(path)**.

After a request is made, the `sign` method starts recursively calling itself in order to wait while the [MPC signing service](#3-mpc-signing-service) signs the payload.

<details>
<summary> A Contract Recursively Calling Itself? </summary>

NEAR smart contracts are unable to halt execution and await the completion of a process. To solve this, one can make the contract call itself again and again checking on each iteration if the result is ready.

Note that each call will take one block, and thus result on ~1s of waiting. After some time the contract will either return a result - since somebody external provided it - or run out of GAS waiting.

</details>

<hr class="subsection" />

### 3. MPC Signing Service

A multi-party computation service (`MPC service`, see more below) is constantly listening for signature requests (i.e. users calling the `sign` method). When a call is detected, the service will:

1. Use the `accountId` of the requester, and the `path` (in our example, `ethereum-1`) to derive a key
2. Sign the `payload` (in our example, a transaction transferring ETH) using the stored key
3. Call the contract `multichain.near`, storing the resulting `Signature`

:::tip
Every time an account makes a signature request using the same `path`, the same `key` will be derived. This allows to use always the same account to sign different transactions.
:::

<details>
<summary> What is an MPC Service? </summary>

MPC (multi-party computation) allows independent actors to do shared computations on private information, without revealing secrets to each-other.

NEAR uses its own MPC service to safely sign transactions for other chains on behalf of the user. In practice, **no single node** on the MPC can **sign by itself** since they do **not hold the user's keys**. Instead, nodes create signature-shares which are aggregated through multiple rounds to jointly sign the payload.

Generally, MPC signing services work by sharing a master key, which needs to be re-created each time a node joins or leaves. NEAR's MPC service allows for nodes to safely join and leave, without needing to re-derive a master key.

If you want to learn more about how MPC works, we recommend to [**check this article**](https://www.zellic.io/blog/mpc-from-scratch/)

</details>

<hr class="subsection" />

### 4. Relaying the Signature

At this point - assuming the contract didn't run out of gas waiting - the contract will return the response for the signature request. This response is a valid signed transaction that can be readily sent to the target blockchain to be executed.

To simplify relaying the transaction, we are building an indexer that will automatically capture the signature, and submit it to the target chain using a multi-chain [relayer](relayers.md).

:::tip
A multi-chain [relayer](relayers.md) is a service that knows how to relay signed transactions into their target networks so they are executed on-chain.
:::

<!-- ### Workflow

- A NEAR account requests a payload to be signed by a deployed [MPC](#multi-party-computation-mpc) smart contract
> This request is performed by calling `sign` and passing the payload (hash from a message or transaction)
- A key is derived from the MPC root key using `account_id` and derivation path. (this ensures that it will be the same key if the two parameters are the same)
- Once the client gets the signature, it can send the transaction to a relayer
> In a future release, an indexing service will listen to all `sign` events from the MPC contract and will trigger a multi-chain relayer -->
37 changes: 37 additions & 0 deletions docs/1.concepts/abstraction/mpc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
id: mpc
title: Multi-Party Computation (MPC)
---

MPC, or multi-party computation, is about how multiple parties can do shared computations on private inputs without revealing the private data.

As an example, suppose two investors want to compare who holds more crypto tokens without revealing their account balances. MPC can solve this situation, by computing the function `f(x > y)`, where `x` and `y` are private inputs. Each person would submit a private value, and would get the function `x > y` result.

In general, MPC can be used to build all kinds of useful protocols, like threshold cryptography, dark pools, and private auctions. For example, MPC can be used to jointly encrypt a message, with the key split up among many different parties.

<details>
<summary> MPC versus key splitting</summary>
In secret sharing, the key has to get reassembled. At some point, some trusted party is going to have the entire key available to them. With MPC, the whole operation is done in MPC, meaning there's no point where the combined key could be extracted.
</details>

:::info
Want to learn more about multi-party computation? Check [this article](https://www.zellic.io/blog/mpc-from-scratch/).
:::

---

## MPC signature generation

- MPC nodes are doing a multistep process called signature generation.
- They are doing it by using user key shares derived from their root key shares.
- A root key is never reconstructed, but protocol allows to create signatures using it’s shares.

:::info
Using MPC, the root key is never reconstructed and it’s never available. User key is never reconstructed as well.
:::

## How MPC creates a new key

- Once MPC account verification is complete, a root key becomes available to sign a new signature that creates a new key
Copy link
Contributor

Choose a reason for hiding this comment

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

MPC never creates new keys, it just uses derivation of the root key. All accounts have access to their derivation on creation.

Copy link
Collaborator

Choose a reason for hiding this comment

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

this file was a first draft that ended up being orphan (it is in the docs, but linked nowhere)... will delete it in a future PR

- This new key is created using [Additive Key Deriviation](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#specification-key-derivation) (a mechanism for deriving many _sub-keys_ from a single _master key_)
- This new sub-key can now be used to sign a payload for a given account associated with a given blockchain
35 changes: 35 additions & 0 deletions docs/1.concepts/abstraction/relayers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
id: relayers
title: Relayers
---

A relayer is a simple web service that receives transactions from NEAR users, and relays them to the network while attaching tokens to cover their GAS expenses. In this document we present a high-level overview on how relayers work. Please check the [build a relayer](../../2.develop/relayers/welcome.md) page if you want to learn how to build your own relayer.

---

## How it works

Relayers are a natural consequence of [NEP-366: Meta Transactions](https://github.com/near/NEPs/blob/master/neps/nep-0366.md), a special type of transaction which can be best understood as an intent.

The user expresses: "I want to do a specific action on chain" and signs this intent **off-chain**, but does not sends it to the network. Instead, they send the intent to a `Relayer`, which wraps the message into an actual transaction, attaches the necessary funds, and sends it to the network.

<details>
<summary> Technical Details </summary>

Technically, the end user (client) creates a `SignedDelegateAction` that contains the data necessary to construct a `Transaction`, signs the `SignedDelegateAction` using their key, and send it to the relayer service.

When the request is received, the relayer uses its own key to sign a `Transaction` using the fields in the `SignedDelegateAction` as input to create a `SignedTransaction`.

The `SignedTransaction` is then sent to the network via RPC call, and the result is sent back to the client. The `Transaction` is executed in such a way that the relayer pays the GAS fees, but all actions are executed as if the user had sent the transaction.
</details>

---

## Why using a Relayer?
There are multiple reasons to use a relayer:
1. Your users are new to NEAR and don't have any gas to cover transactions
2. Your users have an account on NEAR, but only have a Fungible Token Balance. They can now use the FT to pay for gas
3. As an enterprise or a large startup you want to seamlessly onboard your existing users onto NEAR without needing them to worry about gas costs and seed phrases
4. As an enterprise or large startup you have a user base that can generate large spikes of user activity that would congest the network. In this case, the relayer acts as a queue for low urgency transactions
5. In exchange for covering the gas fee costs, relayer operators can limit where users spend their assets while allowing users to have custody and ownership of their assets
6. Capital Efficiency: Without relayer if your business has 1M users they would have to be allocated 0.25 NEAR to cover their gas costs totalling 250k NEAR. However, only ~10% of the users would actually use the full allowance and a large amount of the 250k NEAR is just sitting there unused. So using the relayer, you can allocate 50k NEAR as a global pool of capital for your users, which can refilled on an as needed basis3.
122 changes: 122 additions & 0 deletions docs/1.concepts/abstraction/signatures/use-case.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
---
id: use-cases
title: Use cases for Chain Signatures
sidebar_label: Use cases
---

Chain signatures enable you to implement multichain and cross-chain workflows in a simple way.
Take a look at a few possible use cases:

---

## Trade Blockchain assets without transactions

Trading assets across different blockchains usually require using a bridge that supports them, bringing longer settlement times as the trades are not atomic and require confirmation on both blockchains.

Using Chain signatures you have the ability to change the ownership of different blockchain accounts (e.g., Bitcoin and Ethereum) to trade assets across chains without doing on-chain transactions.
This way you can keep native tokens on their native blockchain (e.g., `BTC` on Bitcoin, `ETH` on Ethereum, `ARB` on Arbitrum), and trade them without bridges.
As an added bonus, trades are atomic across chains, settlement takes just 2 seconds, and it supports any token on any chain.

For example, a basic trade flow could be:

1. Users create an account controlled by NEAR chain signatures
2. Users funds these accounts on the native blockchains (depositing)
3. Place orders by funding a new account for the total amount of the order
4. Another user accepts the order
5. Users swap control of the keys to fulfill the order

![docs](/docs/native-cross-chain.png)

<details>
- User A has `ETH` on the Ethereum blockchain, and wants to buy native Bitcoin
- User B wants to sell Bitcoin for Ethereum

**Steps**

1. User B, using NEAR, creates and funds a new account on Bitcoin with 1 `BTC`
2. User B, using the spot marketplace smart contract, signs a transaction to create a limit order. This transfers control of the Bitcoin account to the smart contract
3. User A creates a batch transaction with two steps
- Creating and funding a new Ethereum account with 10 `ETH`
- Accepting the order and atomically swapping control of the accounts
4. User A takes ownership of the Bitcoin account with 1 `BTC`, and User B takes ownership of the Ethereum account with 10 `ETH`
5. User A and B can _"withdraw"_ their asset from the order by transferring the assets to their respective _"main"_ accounts
</details>

---

## Oauth-controlled Blockchain accounts

On-boarding is a huge problem for decentralized applications. If you want widespread adoption you can't expect people to keep seed phrases safe in order to use an application.

An attractive way of managing Web3 accounts is to use existing Web2 accounts to on-board users. This can be done in the following way:

1. Deploy a NEAR contract that allows the bearer of a user's [JWT token](https://jwt.io/) to sign a blockchain transaction (Ethereum, Polygon, Avalanche, and others)
2. The user validates their identity with a third-party receiving a JWT Token
3. The user holding that token can interact with blockchain applications on Ethereum/Polygon/+++ via the NEAR contract for the duration of it's validity

Any method of controlling a NEAR account can also be used to control a cross-chain account.

:::info About JWT tokens
JSON Web Tokens are a standard RFC 7519 method for representing claims securely between two parties. They are used in this example to represent the claim that someone is the owner of an Oauth account.
:::

---

## Cross-chain Zero-friction onboarding

Using unique features of the NEAR account model, [Keypom](https://keypom.xyz/) provides zero-friction onboarding and transactions on NEAR. They are generally used for NFT drops, FT drops, and ticketing.

A generic Keypom user-flow could be:

1. The developer creates a restricted NEAR account
2. The account is funded with `NEAR`
3. The user receives a key with limited control of the account
4. The user uses the funded account to call controlled endpoints on NEAR
5. The user returns the remaining funds to the developer and their account is unlocked

:::tip
This allows easy on-boarding to decentralized apps. The accounts are initially restricted to prevent the user being able to simply withdraw the `NEAR` from the account.
:::

## DeFi on Bitcoin (and other non-smart contract chains).

Using chain signatures, smart contracts on NEAR can control externally-owned accounts on non-smart contract chains like Bitcoin, Dogecoin, Ripple, Bittensor, Cosmos Hub, etc. This enables developers to use NEAR as a smart contract “layer” for chains that do not support this functionality natively.

For example, a developer can build a decentralized exchange for Bitcoin Ordinals, using a smart contract on NEAR to manage deposits (into Bitcoin addresses controlled by the contract) and to verify and execute swaps when two users agree to trade BTC for an Ordinal or BRC20 token.

Example:
1. Seller generates a deposit address on Bitcoin that is controlled by the marketplace smart contract on NEAR via chain signatures
2. Seller deposits a Bitcoin Ordinal to the deposit address
3. The Ordinal is listed for sale with a price and a pre-commitment signature from the seller
4. Buyer accepts the order, deposits USDC
5. The control of the Bitcoin Ordinal address is given to the buyer, USDC on NEAR is transferred to the seller

#### Using Chain Signatures

With Chain Signatures you can do the same but across many chains, for example Polygon:

1. The developer creates a restricted NEAR account with a key
2. The account is funded with `NEAR` and `MATIC`
3. The user receives a key with limited control of the account
4. The user uses the funded account to sign payloads calling controlled endpoints on Polygon
5. The user returns the remaining funds to the developer and their account is unlocked

This allows developers to pay for users to use arbitrary contracts on arbitrary chains.

---

## Decentralized Clients

A big problem in decentralized applications is that while the smart contracts are tamper-proof, the clients that access them generally are not. This allows practically complete control over any user account provided they are using the frontend assets that you serve. This has security, trust, and regulatory implications.

When smart contracts can sign payloads you can start using [signed exchanges](https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#name-introduction) (or polyfills) to require HTTP exchanges to be signed by a certain key. If it is not signed with this key the SSL certificate is considered invalid. This means that individual users cannot be served invalid frontends without it being generally observable and non repudiable.

---

## Communication with private NEAR Shards

Companies like [Calimero](https://www.calimero.network/) offer private NEAR shards. Currently, sending messages to and from these NEAR shards is troublesome. If each shard had the ability to sign their message queues, they could be securely sent from one shard to another. Thus you could communicate bidirectionally with any shard as easily as you can with a contract on your own shard.

:::tip
This could also simplify NEAR's sharding model, by treating each NEAR shard like one would a private shard.
:::
Loading
Loading