
Research
Security News
Lazarus Strikes npm Again with New Wave of Malicious Packages
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
github.com/electronic-signatures-industries/nft-marketplace-dag-node
Replaces CosmosSDK chain with a Graphsync network sync
anconsync
with anconsync -peeraddr <seed peer multiaddress> -addr <host multiaddress> -apiaddr <host API address> -data <data directory>
Uses the latest go-ipld-prime
API
DAG Contracts enables a whole set of use cases that regular smart contracts might be too costly or expensive. In this first release, DAG contracts will work with GraphQL queries with immutable CID data.
Further down the road, GraphQL mutations will be used to integrate with onchain platforms, in an agnostic way.
An use case that will be particularly important is for mass or batch NFT metadata updates or creation. With a DAG Contract, you can patch with IPLD Selectors an existing CID, patch with parent CID and new owner, create the new metadata CID, and then send the event to an onchain function, that takes care of minting, or any other business logic.
Ancon IPLD Router Sync uses go-ipld-prime
fsstore which is a streaming enable blockstore that is well performant.
We eventually decided to pick GraphQL for our DAG Contracts technology. With that, expect the following features:
query {
me {
@walk(resumeLink) # Will traverse the link
}
}
query {
me {
@focus(resumeLink)
}
}
Any IPLD events will be mapped to GraphQL Subscriptions
You will have a list of onchain adapters, with EVM adapters being the first to come out.
go mod tidy
go build ./server.go
./server
~/Code/ancon-ipld-router-sync/x/anconsync/codegen$ go run github.com/99designs/gqlgen generate
go run github.com/Khan/genqlient --init
swag init
https://ancon.did.pa/api/swagger/index.html
POST https://ancon.did.pa/api/v0/dagjson
Content-Type: application/json
{
"path": "/",
"data": {
"name": "XDV metadata sample",
"owner": "alice",
"description": "testing sample",
"image": "https://explore.ipld.io/#/explore/QmSnuWmxptJZdLJpKRarxBMS2Ju2oANVrgbr2xWbie9b2D"
}
}
POST https://ancon.did.pa/api/v0/dagcbor
Content-Type: application/json
{
"path": "/",
"data": "<cbor content base64 encoded>"
}
GET https://ancon.did.pa/api/v0/dagcbor/baguqeeraouhd5jr7ktftgkbo5ufmihs3e2yqonajjejhomvbtsrwynlqdxba/
GET https://ancon.did.pa/api/v0/dagjson/baguqeeraouhd5jr7ktftgkbo5ufmihs3e2yqonajjejhomvbtsrwynlqdxba/file.json
https://ancon.did.pa/api/v0/query
Query a dag-json by CID
Mutates existing metadata CID
adapters/ethereum_adapter.go
, in our case a NFT ownership transfer. This must be plugged in to the gateway, either REST or JSON-RPC.func (adapter *EthereumAdapter) ExecuteDagContract(
metadatadCid string,
resultCid string,
fromOwner string,
toOwner string,
) (*DagTransaction, error) {
pk, has := os.LookupEnv("ETHEREUM_ADAPTER_KEY")
if !has {
return nil, fmt.Errorf("environment key ETHEREUM_ADAPTER_KEY not found")
}
privateKey, err := crypto.HexToECDSA(pk)
if err != nil {
return nil, fmt.Errorf("invalid ETHEREUM_ADAPTER_KEY")
}
data, err := ExecuteDagContractWithProofAbiMethod().Inputs.Pack(metadatadCid, fromOwner, resultCid, toOwner)
if err != nil {
return nil, fmt.Errorf("packing for proof generation failed")
}
hash := crypto.Keccak256Hash(data)
signature, err := crypto.Sign(hash.Bytes(), privateKey)
if err != nil {
return nil, fmt.Errorf("signing failed")
}
return &DagTransaction{
MetadataCid: metadatadCid,
ResultCid: resultCid,
FromOwner: fromOwner,
ToOwner: toOwner,
Signature: hexutil.Encode(signature),
}, nil
}
Graphql integration executes the mutation and then the resulting cid is signed by the Durin gateway.
DagContractTrusted.sol
. The signature proof needs to match the gateway signed proof.//SPDX-License-Identifier: Unlicense
pragma solidity ^0.8.4;
import "./IDagContractTrustedReceiver.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/utils/Address.sol";
contract DagContractTrusted is Ownable {
using ECDSA for bytes32;
using Address for address;
string public url;
address private _signer;
mapping(bytes32 => bool) executed;
error OffchainLookup(string url, bytes prefix);
struct DagContractRequestProof {
string metadataCid;
address fromOwner;
address toOwner;
string resultCid;
address toReceiverContractAddress;
bytes32 signature;
}
constructor() {}
function setUrl(string memory url_) external onlyOwner {
url = url_;
}
function setSigner(address signer_) external onlyOwner {
_signer = signer_;
}
function getSigner() external view returns (address) {
return _signer;
}
/**
* @dev Requests a DAG contract offchain execution
*/
function request(address toReceiverContractAddress, uint256 tokenId)
public
returns (bytes32)
{
revert OffchainLookup(
url,
abi.encodeWithSignature(
"requestWithProof(address toReceiverContractAddress, uint256 tokenId, DagContractRequestProof memory proof)",
toReceiverContractAddress,
tokenId
)
);
}
/**
* @dev Requests a DAG contract offchain execution with proof
*/
function requestWithProof(
address toReceiverContractAddress,
uint256 tokenId,
DagContractRequestProof memory proof
) external returns (bool) {
if (executed[proof.signature]) {
return false;
} else {
bytes32 digest = keccak256(
abi.encodePacked(
"\x19Ethereum Signed Message:\n32",
keccak256(
abi.encodePacked(
proof.metadataCid,
proof.fromOwner,
proof.resultCid,
proof.toOwner,
toReceiverContractAddress,
tokenId
)
)
)
);
address recovered = digest.recover(digest, proof.signature);
require(
_signer == recovered,
"Signer is not the signer of the token"
);
executed[proof.signature] = true;
bytes memory data = abi.encodePacked(
toReceiverContractAddress,
tokenId
);
_onDagContractResponseReceived(
toReceiverContractAddress,
address(this),
msg.sender,
proof.metadataCid,
proof.resultCid,
data
);
return true;
}
}
/**
* @dev Receives the DAG contract execution result
*/
// function onDagContractResponseReceived(
// address operator,
// address from,
// string memory parentCid,
// string memory newCid,
// bytes calldata data
// ) external returns (bytes4) {
// return IDagContractTrustedReceiver.onDagContractResponseReceived.selector;
// }
function _onDagContractResponseReceived(
address to,
address operator,
address from,
string memory parentCid,
string memory newCid,
bytes memory _data
) private returns (bool) {
if (to.isContract()) {
try
IDagContractTrustedReceiver(to).onDagContractResponseReceived(
operator,
from,
parentCid,
newCid,
_data
)
returns (bytes4 retval) {
return
retval ==
IDagContractTrustedReceiver
.onDagContractResponseReceived
.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("DagContractTrusted: invalid receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
}
Copyright IFESA 2021
FAQs
Unknown package
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
The Socket Research Team has discovered six new malicious npm packages linked to North Korea’s Lazarus Group, designed to steal credentials and deploy backdoors.
Security News
Socket CEO Feross Aboukhadijeh discusses the open web, open source security, and how Socket tackles software supply chain attacks on The Pair Program podcast.
Security News
Opengrep continues building momentum with the alpha release of its Playground tool, demonstrating the project's rapid evolution just two months after its initial launch.