Skip to content

dudebing99/enclave_in_web3

Repository files navigation

ENCLAVE IN WEB3

GitHub Actions Status GitHub Actions Status GitHub Actions Status

使用场景

  • 在去中心化应用中,一般采用中心化+去中心化混合架构。在中心化后台服务进行业务处理时,需要使用指定合约预设的签名地址对业务数据 进行签名,然后将签名数据在去中心化的合约中进行验签

举例:在一个 NFT 抢购应用中

  1. 当用户发起抢购时,后台服务会根据预设的各项条件进行判断,使用指定的签名地址生成包含 NFT 属性的签名数据
  2. 用户支付代币并携带签名数据与合约进行交互
  3. 合约即可对签名数据进行验证并做相应的处理
  • 交易所热钱包管理

通过在 Keeper 中生成私钥,获取对应的地址和加密之后的私钥。开发、运维、客服人员在可以不需要接触热钱包的前提下实现对热钱包地址 的配置、使用。例如,当用户提现时,需要从热钱包给用户指定的链上地址转账,只需要调用 Keeper 的签名或者转账接口即可实现

  • 交易所用户钱包管理

参考 “交易所热钱包管理”

使用技巧

  • 如果想节省硬件资源,生成瞬时地址,签名时携带加密之后的私钥去请求 Keeper 签名
  • 如果想简化大量的用户钱包管理,使用 HD 方式即可

ENCLAVE CLIENT

接口

  • 测试接口 /api/test/keeper POST

测试 client 与 keeper 通信是否正常

示例请求

curl http://localhost:10000/api/test/keeper -X POST -d '{"echo":"hello"}' -s | jq
{
  "error": {
    "code": 0,
    "msg": "ok"
  },
  "echo": "hello",
  "time": "2025-04-15 09:11:41"
}
  • 生成私钥接口 /api/key/generate POST

示例请求

curl http://localhost:10000/api/key/generate -X POST -d '{}' -s | jq
{
  "error": {
    "code": 0,
    "msg": "ok"
  },
  "key_id": "5ed24411-76fc-4ea7-9887-a8f00df8f01b",
  "address": "0x5Cd6476FF61e5d6792ca3b973ce33764faa871A0",
  "private_key": ""
}

测试模式下,可以返回生成的私钥,生产模式下不建议使用

curl http://localhost:10000/api/key/generate -X POST -d '{"show_private_key":true}' -s | jq
{
  "error": {
    "code": 0,
    "msg": "ok"
  },
  "key_id": "5ed24411-76fc-4ea7-9887-a8f00df8f01b",
  "address": "0x5Cd6476FF61e5d6792ca3b973ce33764faa871A0",
  "private_key": "1db13f9c3a3c91c9949f26040d33504ccb08d71acff4f76782b897a9383b7dc4"
}
  • 添加私钥接口 /api/key/add POST

示例请求

curl http://localhost:10000/api/key/add -X POST -d '{"key_id":"3bf2b6cb-debe-4c75-bb6e-38a35e818680","address":"0x5d1D0e4A7775BD50565af85b679E726648753bC5","private_key":"ac904c67de52249561ea562f3190a7c875346c697ad80d8b037fecf688959293"}' -s | jq
{
  "error": {
    "code": 0,
    "msg": "ok"
  }
}
  • 签名消息接口 /api/sign POST

示例请求

curl http://localhost:10000/api/sign -X POST -d '{"key_id": "f47ac10b-58cc-0372-8567-0e02b2c3d479", "hash": "0x1075797ba87c4cacf7bc34c658471ba6c766993fd05150d77521d5f454e9a0cd"}' -s | jq
{
  "error": {
    "code": 0,
    "msg": "ok"
  },
  "signature": "5a5392e0454e4c68339d62193dc1393082ca03cdf30e856ea54e60931bb1595467879a130cbf3e0149c96ef31f4e4e654adb6daa67541b13cc263d798aa4e27a00"
}

如果请求的签名私钥不存在,错误如下

curl http://localhost:10000/api/sign -X POST -d '{"key_id": "b16a2659-a332-4293-9604-a8d1b3f879a3", "hash": "0x1075797ba87c4cacf7bc34c658471ba6c766993fd05150d77521d5f454e9a0cd"}' -s | jq
{
  "error": {
    "code": 2,
    "msg": "key id: b16a2659-a332-4293-9604-a8d1b3f879a3 not found"
  },
  "signature": ""
}
  • 设置加密种子接口 /api/key/set_encryption_seed POST

示例请求

curl 'http://localhost:10000/api/key/set_encryption_seed' -X POST -d '{"encryption_seed":"oXuVXyjjGR5YdmNxf&Qjut2b-6s*wnU!DOqPSAUW#(5k!rrYnn)uAc_DOL-VkENJU-"}' -s | jq
{
  "error": {
    "code": 0,
    "msg": "ok"
  }
}
  • 生成地址接口 /api/key/generate_address POST

示例请求

curl 'http://localhost:10000/api/key/generate_address' -X POST -d '{"is_hd_wallet": true, "number": 2}' -s | jq
{
  "error": {
    "code": 0,
    "msg": "ok"
  },
  "addresses": [
    {
      "key_id": "8c339fe7-d9a8-4e23-b549-83dc79957cc4",
      "address": "0x041E09Ac4EDf9c8198FBedD82c89FF88D72c67e2",
      "private_key": "",
      "hd_wallet_index": 2
    },
    {
      "key_id": "ee48dc2a-d187-44cf-8e10-fda9f2d5b49c",
      "address": "0xc8bDCB8629C6FaD267D632c3ca358646ee8B1dCd",
      "private_key": "",
      "hd_wallet_index": 3
    }
  ]
}
  • HTTP 响应头部包含 Request-Id,结合日志文件可以追踪业务或者排查错误
< HTTP/1.1 200 OK
< Content-Type: text/plain; charset=utf-8
< Request-Id: 4a80058c306d291
< Date: Tue, 15 Apr 2025 02:59:39 GMT
< Content-Length: 191

ENCLAVE KEEPER

暂无

一键部署

enclave_client 可以(不使用 docker)直接在宿主机 EC2 编译、运行,注释掉脚本相关代码即可

git clone https://github.com/dudebing99/enclave_in_web3.git

cd enclave_in_web3

echo "initialize env ..."
bash init.sh

echo "deploy services ..."
bash deploy.sh

预期输出参考样例

[+] Building 32.1s (16/16) FINISHED                                                                                                                                            docker:default
 => [internal] load build definition from dockerfile_keeper                                                                                                                              0.0s
 => => transferring dockerfile: 796B                                                                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                                         0.1s
 => [internal] load metadata for docker.io/library/golang:1.19-alpine                                                                                                                    0.1s
 => [internal] load .dockerignore                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                          0.0s
 => [builder 1/6] FROM docker.io/library/golang:1.19-alpine@sha256:0ec0646e208ea58e5d29e558e39f2e59fccf39b7bda306cb53bbaff91919eca5                                                      0.0s
 => [stage-1 1/4] FROM docker.io/library/alpine:latest@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099                                                           0.0s
 => [internal] load build context                                                                                                                                                        0.2s
 => => transferring context: 24.52MB                                                                                                                                                     0.2s
 => CACHED [builder 2/6] RUN apk add --no-cache gcc libc-dev make                                                                                                                        0.0s
 => CACHED [builder 3/6] WORKDIR /enclave_in_web3                                                                                                                                        0.0s
 => [builder 4/6] COPY . .                                                                                                                                                               0.4s
 => [builder 5/6] RUN go mod tidy                                                                                                                                                        7.4s
 => [builder 6/6] RUN go build -o bin/enclave-keeper ./cmd/keeper/main.go                                                                                                               23.9s
 => CACHED [stage-1 2/4] WORKDIR /enclave_in_web3                                                                                                                                        0.0s
 => CACHED [stage-1 3/4] COPY --from=builder /enclave_in_web3/bin/enclave-keeper ./                                                                                                      0.0s
 => CACHED [stage-1 4/4] COPY --from=builder /enclave_in_web3/conf/application_keeper.yml ./conf/application.yml                                                                         0.0s
 => exporting to image                                                                                                                                                                   0.0s
 => => exporting layers                                                                                                                                                                  0.0s
 => => writing image sha256:e6d74e77dc4a4f4038dbd94644d9205e7f12421e3c423990655918a119617930                                                                                             0.0s
 => => naming to docker.io/library/enclave_keeper:latest                                                                                                                                 0.0s
[+] Building 29.1s (16/16) FINISHED                                                                                                                                            docker:default
 => [internal] load build definition from dockerfile_client                                                                                                                              0.0s
 => => transferring dockerfile: 810B                                                                                                                                                     0.0s
 => [internal] load metadata for docker.io/library/alpine:latest                                                                                                                         0.1s
 => [internal] load metadata for docker.io/library/golang:1.19-alpine                                                                                                                    0.1s
 => [internal] load .dockerignore                                                                                                                                                        0.0s
 => => transferring context: 2B                                                                                                                                                          0.0s
 => [builder 1/6] FROM docker.io/library/golang:1.19-alpine@sha256:0ec0646e208ea58e5d29e558e39f2e59fccf39b7bda306cb53bbaff91919eca5                                                      0.0s
 => [internal] load build context                                                                                                                                                        0.0s
 => => transferring context: 16.99kB                                                                                                                                                     0.0s
 => [stage-1 1/4] FROM docker.io/library/alpine:latest@sha256:56fa17d2a7e7f168a043a2712e63aed1f8543aeafdcee47c58dcffe38ed51099                                                           0.0s
 => CACHED [builder 2/6] RUN apk add --no-cache gcc libc-dev make                                                                                                                        0.0s
 => CACHED [builder 3/6] WORKDIR /enclave_in_web3                                                                                                                                        0.0s
 => CACHED [builder 4/6] COPY . .                                                                                                                                                        0.0s
 => CACHED [builder 5/6] RUN go mod tidy                                                                                                                                                 0.0s
 => [builder 6/6] RUN go build -o bin/enclave-client ./cmd/client/main.go                                                                                                               28.8s
 => CACHED [stage-1 2/4] WORKDIR /enclave_in_web3                                                                                                                                        0.0s
 => CACHED [stage-1 3/4] COPY --from=builder /enclave_in_web3/bin/enclave-client ./                                                                                                      0.0s
 => CACHED [stage-1 4/4] COPY --from=builder /enclave_in_web3/conf/application_client.yml ./conf/application.yml                                                                         0.0s
 => exporting to image                                                                                                                                                                   0.0s
 => => exporting layers                                                                                                                                                                  0.0s
 => => writing image sha256:37612af8097af3e32bab264c6113f54420dbeb4c0b1be57c2380c1abc094126c                                                                                             0.0s
 => => naming to docker.io/library/enclave_client:latest                                                                                                                                 0.0s
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] Total reclaimed space: 0B
Start building the Enclave Image...
Using the locally available Docker image...
Enclave Image successfully created.
{
  "Measurements": {
    "HashAlgorithm": "Sha384 { ... }",
    "PCR0": "fd27433ffcb75192ab7ee460c8c9cf25e9d13900e749381dd7c23966a3159a3f852af39a0f88ac7c35174e2a626d362c",
    "PCR1": "4b4d5b3661b3efc12920900c80e126e4ce783c522de6c02a2a5bf7af3a2b9327b86776f188e4be1c1c404a129dbda493",
    "PCR2": "9ea41e12380e65ec2f05a47c8a373454d19a202baa42c409c2193bf8af6823c120e27205652e5f04001f02da35a7355f"
  }
}
Start allocating memory...
Started enclave with enclave-cid: 22, memory: 3000 MiB, cpu-ids: [1, 3]
{
  "EnclaveName": "enclave_keeper",
  "EnclaveID": "i-0a8d6cd7bed188be7-enc194d70c4c759219",
  "ProcessID": 42971,
  "EnclaveCID": 22,
  "NumberOfCPUs": 2,
  "CPUIDs": [
    1,
    3
  ],
  "MemoryMiB": 3000
}

参考资料

已知问题

  • rlp: too few elements ... 参考 https://github.com/ethereum/go-ethereum/issues/26236

About

enclave in web3(web3 enclave 实践,包含私钥管理、离线签名,适用于交易所、钱包、dapp 后端)

Topics

Resources

Stars

Watchers

Forks

Releases

Packages

Used by

Contributors

Languages