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

update ontid contract; merge to solve pr#7; #11

Merged
merged 7 commits into from
Apr 9, 2018
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
11 changes: 6 additions & 5 deletions src/consts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export const ALGORITHM_TYPE = {
}

export const TEST_NODE = '139.219.111.50'
// export const TEST_NODE = '192.168.3.97'
// export const TEST_NODE = '192.168.50.10'

// export const TEST_NODE = '54.222.182.88'
export const MAIN_NODE = '54.222.182.88'
Expand All @@ -63,7 +63,8 @@ export const HTTP_JSON_PORT = '20336'

export const REST_API = {
getBalance: '/api/v1/balance',
sendRawTx: '/api/v1/transaction'
sendRawTx: '/api/v1/transaction',
getMerkleProof : '/api/v1/merkleproof' // end with /txHash
}


Expand All @@ -73,11 +74,11 @@ export const ONT_NETWORK = {
}

export const TEST_ONT_URL = {
SOCKET_URL: `ws://${TEST_NODE}:${HTTP_WS_PORT}/`,
SOCKET_URL: `ws://${TEST_NODE}:${HTTP_WS_PORT}`,

RPC_URL: `http://${TEST_NODE}:${HTTP_JSON_PORT}/`,
RPC_URL: `http://${TEST_NODE}:${HTTP_JSON_PORT}`,

REST_URL: `http://${TEST_NODE}:${HTTP_REST_PORT}/`,
REST_URL: `http://${TEST_NODE}:${HTTP_REST_PORT}`,

sendRawTxByRestful : `http://${TEST_NODE}:${HTTP_REST_PORT}${REST_API.sendRawTx}`
}
Expand Down
115 changes: 113 additions & 2 deletions src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@ import * as base58 from 'bs58'
import * as ecurve from 'ecurve'
import * as bigInteger from 'bigi'
import { ab2hexstring, hexstring2ab, StringReader, hexstr2str, num2hexstring } from './utils'
import { ADDR_VERSION, TEST_ONT_URL } from './consts'
import { ADDR_VERSION, TEST_ONT_URL, REST_API } from './consts'
import * as scrypt from './scrypt'
import {ERROR_CODE} from './error'
import { VmType } from './transaction/vmcode';
import { buildGetDDOTx, buildRestfulParam, sendRawTxRestfulUrl} from './transaction/transactionBuilder'
import { buildRestfulParam, sendRawTxRestfulUrl} from './transaction/transactionBuilder'
import axios from 'axios'
import { DDO } from './transaction/ddo'
import { getPublicKeyStatus, buildGetDDOTx } from './smartcontract/ontidContract'
import { verifyLeafHashInclusion } from './merkle'

var ec = require('elliptic').ec
var wif = require('wif')
Expand Down Expand Up @@ -249,4 +251,113 @@ export function verifyOntidClaim(claim : any) {
}
}
})
}

const getDDO = (ontid : string, url ?: string) => {
let tx = buildGetDDOTx(ontid)
let param = buildRestfulParam(tx)
url = url || TEST_ONT_URL.REST_URL
let requestUrl = sendRawTxRestfulUrl(url , true)
return axios.post(requestUrl, param).then((res: any) => {
if (res.data.Result && res.data.Result.length > 0) {
console.log('ddo hexstr: ' + res.data.Result[0])
const ddo = DDO.deserialize(res.data.Result[0])
console.log('ddo: ' + JSON.stringify(ddo))
return ddo
}
})
}

export const getMerkleProof = (txHash : string, url ?: string) => {
url = url || TEST_ONT_URL.REST_URL
let requestUrl = `${url}${REST_API.getMerkleProof}/${txHash} `
return axios.get(requestUrl).then((res:any)=> {
console.log('merkle : ' + JSON.stringify(res.data))
return res.data.Result
})
}

const getRovocationList = (url : string) => {
return axios.get(url).then(res => {
return res.data
})
}

const VerifyOntidClaimResult = {
CLAIM_NOT_ONCHAIN : 'CLAIM_NOT_ONCHAIN',
INVALID_SIGNATURE : 'INVALID_SIGNATURE',
PK_IN_REVOKEED : 'PK_IN_REVOKED',
EXPIRED_CLAIM : 'EXPIRED_CLAIM',
REVOKED_CLAIM : 'REVOKED_CLAIM',
VALID_CLAIM : 'VALID_CLAIM'
}

/*
*@claim : claim json object
*@url : the node to send tx, eg: http://192.168.3.111:20334
*/

export async function verifyOntidClaimAsync(claim : any, url ?: string) {
if (!claim.Metadata || !claim.Metadata.Issuer) {
throw new Error('Invalid claim.')
}

//verify expiration
const expiration = new Date( claim.Metadata.Expires )
let d = new Date()
if(d > expiration) {
return VerifyOntidClaimResult.EXPIRED_CLAIM
}

// verify signature
let issuerDid = claim.Metadata.Issuer
//issuer is : ONTID#PkId
let issuerPkId = issuerDid.substr(issuerDid.indexOf('#') + 1)
//pkStatus = { publicKey, status : [IN USE, Revoked] }
let pkStatus = await getPublicKeyStatus(issuerDid, issuerPkId, url)
if (pkStatus.status === 'Revoked') {
return VerifyOntidClaimResult.PK_IN_REVOKEED
}

//verify signature
const pk = pkStatus.publicKey.substr(0,4) === '1202' ? pkStatus.publicKey.substr(4) : pkStatus.publicKey
//the order of claim's attributes matters.
let signature = Object.assign({}, {
Context: claim.Context,
Id: claim.Id,
Content: claim.Content,
Metadata: claim.Metadata,
})

let result = verifySignature(JSON.stringify(claim), JSON.stringify(signature), hexstring2ab(pk))
if(!result) {
return VerifyOntidClaimResult.INVALID_SIGNATURE
}
if(claim.Proof) {
// verify merkle
let merkle = claim.Proof
const leafHash = merkle.BlockRoot
const leafIndex = merkle.BlockHeight
const proof = merkle.TargetHashes
const rootHash = merkle.CurBlockRoot
const treeSize = merkle.CurBlockHeight

let verifyMerkleResult = verifyLeafHashInclusion(leafHash, leafIndex, proof, rootHash, treeSize)
if (!verifyMerkleResult) {
return VerifyOntidClaimResult.CLAIM_NOT_ONCHAIN
}
}


//verify revoke - optional
if(claim.Metadata.Revocation) {
let url = claim.Metadata.Crl
if(claim.Metadata.Revocation === 'RevocationList' && claim.Metadata.Crl) {

} else if(claim.Metadata.Revocation === 'RevocationUrl') {

}
}

return VerifyOntidClaimResult.VALID_CLAIM
}
32 changes: 32 additions & 0 deletions src/crypto.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { StringReader } from "./utils";

export enum SignatureSchema {
SHA224withECDSA = 0,
SHA256withECDSA,
Expand Down Expand Up @@ -35,4 +37,34 @@ export class PublicKey {
algorithm: number
curve: number
pk: string

static deserialize(sr : StringReader) {
let pub = new PublicKey()
const algorithm = parseInt(sr.read(1), 16)
const curve = parseInt(sr.read(1),16)
const pk = sr.read(33)
pub.algorithm = algorithm
pub.curve = curve
pub.pk = pk
return pub
}
}

export enum PK_STATUS {
IN_USE = '01',
REVOKED = '00'
}

export class PublicKeyStatus {
pk : PublicKey
status : string

static deserialize(hexstr : string) : PublicKeyStatus {
let ps = new PublicKeyStatus()
const sr = new StringReader(hexstr)
const status = sr.read(1)
ps.status = status
ps.pk = PublicKey.deserialize(sr)
return ps
}
}
2 changes: 1 addition & 1 deletion src/identity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import * as scrypt from './scrypt'
import { ab2hexstring, hexstring2ab } from './utils'
import {DEFAULT_ALGORITHM, Algorithm} from './consts'
import {ERROR_CODE} from './error'
import { buildGetDDOTx, buildRegisterOntidTx, buildRestfulParam } from './transaction/transactionBuilder';
import { buildRestfulParam } from './transaction/transactionBuilder';
import { checkPrivateKey } from './core';

export class ControlData {
Expand Down
77 changes: 77 additions & 0 deletions src/merkle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Copyright (C) 2018 The ontology Authors
* This file is part of The ontology library.
*
* The ontology is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The ontology is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with The ontology. If not, see <http://www.gnu.org/licenses/>.
*/

import * as cryptoJS from 'crypto-js'


/*
verify a Merkle Audit Path

leaf_hash: The hash of the leaf for which the proof was provided.
leaf_index: Index of the leaf in the tree.
proof: A list of SHA-256 hashes representing the Merkle audit path.
tree_size: The size of the tree
root_hash: The root hash of the tree

Returns:
true when the proof is valid
*/
export function verifyLeafHashInclusion(leafHash : string, leafIndex : number, proof : Array<string>,
rootHash : string, treeSize : number) {
if(treeSize <= leafIndex) {
throw new Error('Wrong params, the tree size is smaller than the leaf index')
}

let calculatedRootHash = calculateRootHashFromAuditPath(leafHash, leafIndex, proof, treeSize)
if(calculatedRootHash !== rootHash) {
return false
}
return true
}

export function calculateRootHashFromAuditPath(leafHash : string, leafIndex : number, proof : Array<string>, treeSize : number) {
let calculatedHash = leafHash
let lastNode = treeSize - 1
let pos = 0
let pathLen = proof.length
while(lastNode > 0) {
if(pos > pathLen) {
throw new Error('Proof too short');
}
if(leafIndex % 2 ===1) {
calculatedHash = hashChildren(proof[pos], calculatedHash)
pos += 1
} else if (leafIndex < lastNode ){
calculatedHash = hashChildren(calculatedHash, proof[pos])
pos += 1
}
leafIndex = Math.floor( leafIndex / 2 )
lastNode = Math.floor( lastNode / 2)
}
if(pos < pathLen) {
throw new Error('Proof too long')
}
return calculatedHash
}

export function hashChildren(left : string, right : string) {
let data = '01' + left
data += right
let hex = cryptoJS.enc.Hex.parse(data);
return cryptoJS.SHA256(hex).toString();
}
10 changes: 9 additions & 1 deletion src/sdk/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ import {Claim, Metadata, Signature} from '../claim'
import * as scrypt from '../scrypt'
import {sendBackResult2Native, EventEmitter, str2hexstr, ab2hexstring} from '../utils'
import * as core from '../core'
import {buildAddAttributeTx, buildTxParam, buildRpcParam, buildRegisterOntidTx, parseEventNotify, buildGetDDOTx, makeTransferTransaction, buildRestfulParam, sendRawTxRestfulUrl} from '../transaction/transactionBuilder'
import { buildTxParam, buildRpcParam, parseEventNotify, makeTransferTransaction, buildRestfulParam, sendRawTxRestfulUrl} from '../transaction/transactionBuilder'
import { buildAddAttributeTx, buildRegisterOntidTx, buildGetDDOTx} from '../smartcontract/ontidContract'
import { ERROR_CODE } from '../error';
import { ONT_NETWORK, TEST_NODE, REST_API, HTTP_REST_PORT, TEST_ONT_URL } from '../consts';
import { encrypt } from '../scrypt';
Expand Down Expand Up @@ -364,6 +365,13 @@ export class SDK {
callback && sendBackResult2Native(JSON.stringify(obj), callback)
socket.close()
}
if(res.Error !== 0) {
let obj = {
error : res.Error,
result : ''
}
callback && sendBackResult2Native(JSON.stringify(obj), callback)
}
}

txSender.sendTxWithSocket(param, socketCallback)
Expand Down
Binary file added src/smartcontract/data/IdContract.avm
Binary file not shown.
43 changes: 42 additions & 1 deletion src/smartcontract/data/idContract.abi.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export default {
"hash": "80a45524f3f6a5b98d633e5c7a7458472ec5d625",
"hash": "8055b362904715fd84536e754868f4c8d27ca3f6",
"entrypoint": "Main",
"functions":
[
Expand Down Expand Up @@ -196,6 +196,47 @@ export default {
],
"returntype": "ByteArray"
},
{
"name": "GetPublicKeyId",
"parameters":
[
{
"name": "ontId",
"type": "ByteArray"
},
{
"name": "publicKey",
"type": "ByteArray"
}
],
"returntype": "ByteArray"
},
{
"name": "GetPublicKeyStatus",
"parameters":
[
{
"name": "ontId",
"type": "ByteArray"
},
{
"name": "pkId",
"type": "ByteArray"
}
],
"returntype": "ByteArray"
},
{
"name": "GetRecovery",
"parameters":
[
{
"name": "ontId",
"type": "ByteArray"
}
],
"returntype": "ByteArray"
},
{
"name": "GetDDO",
"parameters":
Expand Down
Binary file removed src/smartcontract/data/idContract.avm
Binary file not shown.
Binary file removed src/smartcontract/data/idContract_v0.2.avm
Binary file not shown.
Loading