Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
ethr-did-registry
Advanced tools
A repository storing keys and other data about Decentralized Identifiers (DIDs)
This contract allows on and off-chain resolving and management for DIDs (Decentralized IDentifiers).
A DID is an Identifier that allows you to lookup a DID document that can be used to authenticate you and messages created by you.
It was designed as a way of resolving public keys for off chain authentication, where the public key resolution is handled through the use of decentralized technology.
This contract allows ethereum addresses to present signing information about themselves with no prior registration. It allows them to perform key rotation and specify different keys and services that can be used on it's behalf for both on and off-chain usage.
The DID Registry can be used from javascript as well as directly from other contracts.
To use the contract we provide truffle artifacts. Once you require the ethr-did-registry
module you will get an object containing the json.
const DidRegistryContract = require('ethr-did-registry')
You can use truffle-contract
to utilize these artifacts.
const Contract = require('truffle-contract')
let DidReg = Contract(DidRegistryContract)
DidReg.setProvider(web3.currentProvider)
let didReg = DidReg.deployed()
You can also use web3.
let networkId = 1 // Mainnet
let DidReg = web3.eth.contract(DidRegistryContract.abi)
let didReg = DidReg.at(DidRegistryContract.networks[networkId].address)
Network | Address |
---|---|
Mainnet (id: 1) | 0x160c5ce58e2cc4fe7cc45a9dd569a10083b2a275 |
Ropsten (id: 3) | 0x160c5ce58e2cc4fe7cc45a9dd569a10083b2a275 |
Rinkeby (id: 4) | 0x160c5ce58e2cc4fe7cc45a9dd569a10083b2a275 |
Kovan (id: 42) | 0x160c5ce58e2cc4fe7cc45a9dd569a10083b2a275 |
For on-chain interactions Ethereum has a built in account abstraction that can be used regardless of wether the account is a smart contract or a key pair. Any transaction has a msg.sender
as the verified send of the transaction.
Since each Ethereum transaction has to be funded, there is a growing trend of on-chain transactions that are authenticated via an externally created signature and not by the actual transaction originator. This allows 3rd party funding services or receiver pays without any fundamental changes to the underlying Ethereum architecture.
These kinds of transactions have to be signed by an actual key pair and thus can not be used to represent smart contract based Ethereum accounts.
We propose a way of a Smart Contract or regular key pair delegating signing for various purposes to externally managed key pairs. This allows a smart contract to be represented both on-chain as well as off-chain or in payment channels through temporary or permanent delegates.
Any ethereum account regardless of it being a key pair or smart contract based is considered to be an account identifier.
No registration is needed by an identity.
Each identity has a single address which maintains ultimate control over it. By default each identity is controlled by itself. As ongoing technological and security improvements happen an owner can replace themselves with any other ethereum address, such as an advanced multi signature contract.
There is only ever a single identity owner. More advanced ownership models can be managed through a multi signature contract.
Ownership of an identity can be verified by calling the identityOwner(address identity) public view returns(address)
function. This returns the address of the current Identity Owner.
The account owner can replace themselves at any time, by calling the changeOwner(address identity, address newOwner)
function.
There is also a version of this function which can be called with an externally created signature, that can be passed to a transaction funding service.
The externally signed version has the following signature changeOwnerSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, address newOwner)
.
The signature should be signed of the keccak256 hash of the following tightly packed parameters:
byte(0x19), byte(0), address of registry, nonce[currentOwner], identity, "changeOwner", newOwner
Delegates are addresses that are delegated for a specific time to perform some sort of function on behalf of an identity.
They can be accessed both on and off-chain.
The type of function is simply a string, that is determined by a protocol or application higher up.
Examples:
Delegates expire. Expiration time is application specific and also dependent on the security requirements of the identity owner.
Validity is set using amount of seconds from the time that adding the delegate is set.
You can check if an address is a delegate for an identity using thevalidDelegate(address identity, string delegateType, address delegate) returns(bool)
function. This returns true if the address is a valid delegate of the given delegateType.
The registry provides a handy function for checking an externally signed signature in your own contracts and validating it is a particular kind of delegate.
This frees you from adding nonce and signature management code in your own contracts.
validDelegateSignature(address identity, string delegateType, uint8 sigV, bytes32 sigR, bytes32 sigS, bytes32 hash) public returns(address)
In your own code you will need to calculate the hash yourself.
An identity can assign multiple delegates to manage signing on their behalf for specific purposes.
The account owner can call the addDelegate(address identity, string delegateType, address delegate, uint validity)
function.
There is also a version of this function which can be called with an externally created signature, that can be passed to a transaction funding service.
The externally signed version has the following signature addDelegateSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, string delegateType, address delegate, uint validity)
.
The signature should be signed of the keccak256 hash of the following tightly packed parameters:
byte(0x19), byte(0), address of registry, nonce[currentOwner], identity, "addDelegate", delegateType, delegate, validity
A delegate may be manually revoked by calling the revokeDelegate(address identity, string delegateType, address delegate)
function.
There is also a version of this function which can be called with an externally created signature, that can be passed to a transaction funding service.
The externally signed version has the following signature revokeDelegateSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, string delegateType, address delegate)
.
The signature should be signed of the keccak256 hash of the following tightly packed parameters:
byte(0x19), byte(0), address of registry, nonce[currentOwner], identity, "revokeDelegate", delegateType, delegate
Attributes are stored as DIDDelegateChanged
events. A validTo
of 0 indicates a revoked delegate.
event DIDDelegateChanged(
address indexed identity,
string delegateType,
address delegate,
uint validTo,
uint previousChange
);
An identity may need to publish some information that is only needed off-chain, but still requires the security benefits of using a blockchain.
These attributes are set using the setAttribute(address identity, string name, bytes value, uint validity)
function and published using events.
There is also a version of this function which can be called with an externally created signature, that can be passed to a transaction funding service.
The externally signed version has the following signature setAttributeSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, string name, bytes value, uint validity)
.
The signature should be signed of the keccak256 hash of the following tightly packed parameters:
byte(0x19), byte(0), address of registry, nonce[currentOwner], identity, "setAttribute", name, value, validity
These attributes are revoked using the revokeAttribute(address identity, string name, bytes value)
function and published using events.
There is also a version of this function which can be called with an externally created signature, that can be passed to a transaction funding service.
The externally signed version has the following signature revokeAttributeSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, string name, bytes value)
.
The signature should be signed of the keccak256 hash of the following tightly packed parameters:
byte(0x19), byte(0), address of registry, nonce[currentOwner], identity, "revokeAttribute", name, value
Attributes are stored as DIDAttributeChanged
events. A validTo
of 0 indicates a revoked attribute.
event DIDAttributeChanged(
address indexed identity,
string name,
bytes value,
uint validTo,
uint previousChange
);
Contract Events are a useful feature for storing data from smart contracts exclusively for off-chain use. Unfortunately current ethereum implementations provide a very inefficient lookup mechanism.
By using linked events, that always link to the previous block with a change for the identity we can solve this problem with much improved performance.
Each identity has it’s previously changed block stored in the changed
mapping.
previousChange
block for identitypreviousChange
blockpreviousChange
from the event and repeatExample code
const history = []
previousChange = await didReg.changed(identity)
while (previousChange) {
const filter = await didReg.allEvents({topics: [identity], fromBlock: previousChange, toBlock: previousChange})
const events = await getLogs(filter)
previousChange = undefined
for (let event of events) {
history.unshift(event)
previousChange = event.args.previousChange
}
}
The primary owner key should be looked up using identityOwner(identity)
. This should be the first of the publicKeys listed.
Iterate thought the DIDDelegateChanged
events to build a list of additional keys and authentication sections as needed. The list of delegateTypes to include is still to be determined.
Iterate through DIDAttributeChanged
events for service entries, encryption public keys and other public names. The attribute names are still to be determined.
First run,
$ scripts/generateDeployTxs.js
you will get the data needed to deploy as an output from this command. Copy the senderAddress
and send cost
amount of ether to this address on the ethereum network you wish to deploy to. Once this tx is confirmed simply send the rawTx
to the same network. contractAddress
is the address of the deployed contract. This will be the same on all networks it is deployed to.
Make sure you have truffle installed then simply run:
$ truffle test
FAQs
A repository storing keys and other data about Ethereum Decentralized Identifiers (DIDs)
The npm package ethr-did-registry receives a total of 381 weekly downloads. As such, ethr-did-registry popularity was classified as not popular.
We found that ethr-did-registry demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.