Git Product home page Git Product logo

pw-lock's Introduction

pw-lock

Forked from CKB's system scripts, and currently supports signature generated by personalSign and signTypedData from ethereum wallets.

The CKB system script secp256k1_blake160_sighash_all uses blake2b to calculate the hash, and secp256k1_ecdsa_recover for signature verification. The main difference between CKB and the Ethereum signature verification is the hash calculation method. Ethereum uses keccak256 instead of blake2b to calculate the hash.

Quick Start

git submodule init
git submodule update
make install-tools
make all-via-docker
cargo test --all

Script Implementation

In view of the fact that EIP712 can show users more intuitive and safe information, pw-lock preferentially supports EIP712 related signature method eth_signTypedData_v4. However, currently only a few ETH wallets can fully support EIP712. In order to fully support the Ethereum ecosystem, pw-lock also adapts to the personalSign signature currently supported by most Ethereum wallets.

pw-lock script provides two signature verification methods: eth_personalSign and eth_signTypedData_v4.

eth_personalSign

hash calculation

The same hash calculation process is the same as the CKB system lock script [secp256k1_blake160_sighash_all.c] (https://github.com/nervosnetwork/ckb-system-scripts/blob/master/c/secp256k1_blake160_sighash_all.c), but replace blake2b into keccak256.

signature verification

// pseudo code, the actual code is written in C language
const newHash = hashPersonalMessage(hash)

/*
hashPersonalMessage = function(message: Buffer): Buffer {
  const prefix = Buffer.from(
    `\u0019Ethereum Signed Message:\n${message.length.toString()}`,
    'utf-8',
  )
  return keccak(Buffer.concat([prefix, message]))
}
*/

const pubkey = secp256k1_ecdsa_recover(signature, newHash)
if (pubkey.slice(12, 32) === lock.args){
    return 0;
}
  1. Use the ECDSA_RECOVER algorithm to calculate the 32-byte pubkey from the personalHash and signature.
  2. Check if the last 20 bytes of pubkey are equal to lock args (that is, Ethereum address).

eth_signTypedData_v4

hash calculation

The hash calculation process is the same as the CKB system lock script, except that blake2b is replaced by keccak256.

signature verification

// pseudo code, the actual code is written in C language
const newHash = hashPersonalMessage(hash)
const typedData = {
    domain: {
      chainId: 1,
      name: 'ckb.pw',
      verifyingContract: '0xCcCCccccCCCCcCCCCCCcCcCccCcCCCcCcccccccC',
      version: '1'
    },

    message: {
      hash:
        '0x545529d4464064d8394c557afb06f489e7044a63984c6113385431d93dcffa1b',
      fee: '0.00100000CKB',
      'input-sum': '100.00000000CKB',
      to: [
        {
          address: 'ckb1qyqv4yga3pgw2h92hcnur7lepdfzmvg8wj7qwstnwm',
          amount: '100.00000000CKB'
        },
        {
          address:
            'ckb1qftyhqxwuxdzp5zk4rctscnrr6stjrmfjdx54v05q8t3ad3493m6mhcekrn0vk575h44ql9ry53z3gzhtc2exudxcyg',
          amount: '799.99800000CKB'
        }
      ]
    },
    primaryType: 'CKBTransaction',
    types: {
      EIP712Domain: [
        { name: 'name', type: 'string' },
        { name: 'version', type: 'string' },
        { name: 'chainId', type: 'uint256' },
        { name: 'verifyingContract', type: 'address' }
      ],
      CKBTransaction: [
        { name: 'hash', type: 'bytes32' },
        { name: 'fee', type: 'string' },
        { name: 'input-sum', type: 'string' },
        { name: 'to', type: 'Output[]' }
      ],
      Output: [
        { name: 'address', type: 'string' },
        { name: 'amount', type: 'string' }
      ]
    }
}

typedData.message.hash = newHash
typedData.message['input-sum'] = total_input_amount(tx)
typedData.message.fee = total_input_amount(tx) - total_output_amount(tx)
typedData.message.to = extractTxOutputsInfo(tx)

According to the CKB transaction information, input-sum / fee / to related informations are calculated and assigned to the corresponding attribute of typedData.

signature verification

// pseudo code, the actual code is written in C language

const sigUtil = require('eth-sig-util')

const typedHash =  sigUtil.TypedDataUtils.sign(typedData)
const pubkey = secp256k1_ecdsa_recover(signature, typedHash) 
if( pubkey.slice(12,32) === lock.args){
    return 0;
}
  1. Calculate typedHash by typedData, and use ECDSA_RECOVER algorithm to calculate 32-byte pubkey from typedHash and signature.
  2. Check if the last 20 bytes of pubkey are equal to lock args (that is, Ethereum address).

Anyone-can-pay Support

pw-lock also integrates the features of anyone-can-pay, which is consistent with the official anyone-can-pay

pw-lock's People

Contributors

johnz1019 avatar johnsonzhh avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.