cosigneth, is a decentralized application that runs on Ethereum Rinkeby Testnet. Each signature stored as an NFT using EIP-721 standard. Sign your image digest using your public address and verify them on the blockchain by Solidity contract. Custom serverless function is created to interact with OCI registiries with your given JWT token. We use ethers.signMessage() to sign given image digest using your injected wallet. By giving digest and corresponding signature, we can recover public wallet address by using ECDSA-tryRecover method. See Appendix F in yellowpaper for more information.
Active contract: 0x1a0278c2402aa06d88a8d29c0cac8422e983bd55
- Injected Wallet (Metamask, etc.)
- An Ethereum wallet address
- Switch network to Rinkeby
- Request 0.1 test ETH from Chainlink Faucet
- Jump to https://cosigneth.dev
- Connect your wallet
- Create a registry token
$ curl -L -X POST 'https://auth.docker.io/token' \
-H 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=$USERNAME' \
--data-urlencode 'password=$PASSWORD' \
--data-urlencode 'service=registry.docker.io' \
--data-urlencode 'client_id=dockerengine' \
--data-urlencode 'access_type=offline' \
--data-urlencode 'scope=repository:$IMAGE:pull,push'
Replace
$USERNAME
,$PASSWORD
and$IMAGE
with yours to get an access token from Docker Registry v2 with300
s expire duration. This is an example for Docker Registry.
- Pass your OCI image reference and token (Without Bearer)
- Wait until image reference validation and signing process
- Done! Click the generated Transaction Hash (Txn) on the UI and jump to Etherscan
- Jump to https://cosigneth.dev
- Connect your wallet
- Pass your OCI image reference and a public wallet address
- Wait until fetching signature tags from registry API and verifying process on EVM
- Done! Check your verification result on the UI
sequenceDiagram
autonumber
Frontend->>Web3.js: Initialize Contract ABI
Frontend->>Web3.js: window.ethereum
Web3.js->>+Wallet: Connect
Wallet--)-Frontend: Accounts
Note over Frontend: Sign
rect rgba(0, 0, 255, .1)
Frontend->>+Function: Image Check Prelight
Function--)-Frontend: Return Digest
Frontend->>+Web3.js: web3.eth.sign()
Web3.js--)-Frontend: Signature
Frontend->>+Ethereum: mint()
Ethereum--)-Frontend: Transaction Hash
Frontend->>+Function: Attach ETH Object to Image
Function--)-Frontend: Status Code
end
Note over Frontend: Verify
rect rgba(0, 255, 0, .1)
Frontend->>+Function: Get ETH Object
Function--)-Frontend: Signatures
Frontend->>+Ethereum: nft.methods.verify()
Ethereum--)-Frontend: Verify Result
end
You can use crane to check your .eth
tag:
$ crane ls furkanturkal/busybox
0.2.0
sha256-c734ddd2cee195855d0b5b1906afdf84b68940bc736fca03e2d05d2bd228ea9d.eth
$ crane manifest furkanturkal/busybox:sha256-c734ddd2cee195855d0b5b1906afdf84b68940bc736fca03e2d05d2bd228ea9d.eth | jq
You should expect the following output:
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"size": 233,
"digest": "sha256:0a151380f4116c9388e53fd6fae56e0769eaf539e6a5e67116a40f37a8e24f20"
},
"layers": [
{
"mediaType": "application/vnd.dev.cosign.simplesigning.v1+json",
"size": 252,
"digest": "sha256:4a9735466ab2e5ddf42968a8e283fc2232b04b8c3a93cb710a934d6307ea220f",
"annotations": {
"dev.cosignproject.cosign/blockchain": "Ethereum",
"dev.cosignproject.cosign/chainId": "4",
"dev.cosignproject.cosign/network": "rinkeby",
"dev.cosignproject.cosign/signature": "0x5c4d29575dbb038b12ee2cc49911a8418c243fd404b8c0dfd13e3a24de244c3d7b45e23521a880e6972df76305c662ace2b93006e09865a3e10194cb2bfb30731b",
"dev.cosignproject.cosign/signer": "0xd8f88dc38071f700ee5003ebfef73266cf16e5f1",
"dev.cosignproject.cosign/timestamp": "1647261544",
"dev.cosignproject.cosign/transaction": "0x3f09bbc6ada48c1233bf9f1167c427483234312f8ee907efaa9f91a618aef36f"
}
}
]
}
Because, why not? NFTs are trend topic nowadays. This idea is a good opportunity to create a decentralized application from scratch. Building a website using Next.js with Material UI was a good experince. We learned to interact with the contract using Web3.js.
$ cd src
$ yarn install
$ yarn dev
$ cd src/functions
$ go run . -port 8080
- If transaction failed, we attach ETH object anyway. (not actually signed but it will look like that)
- We haven't a resiliency mechanism in case we couldn't talk with Registry API. (actually signed but won't look like that)
- Reverse proxy does not work well on localhost if you want to run local server.
The base project code is licensed under Apache License 2.0 unless otherwise specified. Please see the LICENSE file for more information.