Skip to content

Commit

Permalink
tokens internal
Browse files Browse the repository at this point in the history
  • Loading branch information
alex v committed Nov 10, 2024
1 parent 847e55c commit dce6216
Show file tree
Hide file tree
Showing 44 changed files with 1,471 additions and 220 deletions.
8 changes: 8 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -197,12 +197,17 @@ BLSCT_H = \
blsct/set_mem_proof/set_mem_proof_prover.h \
blsct/set_mem_proof/set_mem_proof_setup.h \
blsct/signature.h \
blsct/tokens/info.h \
blsct/tokens/predicate.h \
blsct/tokens/predicate_parser.h \
blsct/tokens/rpc.h \
blsct/wallet/address.h \
blsct/wallet/hdchain.h \
blsct/wallet/helpers.h \
blsct/wallet/import_wallet_type.h \
blsct/wallet/keyman.h \
blsct/wallet/keyring.h \
blsct/wallet/rpc.h \
blsct/wallet/txfactory.h \
blsct/wallet/txfactory_global.h \
blsct/wallet/verification.h
Expand Down Expand Up @@ -247,6 +252,7 @@ BLSCT_CPP = \
blsct/set_mem_proof/set_mem_proof_prover.cpp \
blsct/set_mem_proof/set_mem_proof_setup.cpp \
blsct/signature.cpp \
blsct/tokens/predicate_parser.cpp \
blsct/wallet/verification.cpp


Expand Down Expand Up @@ -559,6 +565,7 @@ libbitcoin_node_a_SOURCES = \
blsct/set_mem_proof/set_mem_proof.cpp \
blsct/set_mem_proof/set_mem_proof_setup.cpp \
blsct/set_mem_proof/set_mem_proof_prover.cpp \
blsct/tokens/rpc.cpp \
blsct/wallet/verification.cpp \
blsct/signature.cpp \
chain.cpp \
Expand Down Expand Up @@ -716,6 +723,7 @@ libbitcoin_wallet_a_SOURCES = \
blsct/wallet/helpers.cpp \
blsct/wallet/keyman.cpp \
blsct/wallet/keyring.cpp \
blsct/wallet/rpc.cpp \
blsct/wallet/txfactory.cpp \
blsct/wallet/txfactory_global.cpp \
blsct/wallet/verification.cpp \
Expand Down
9 changes: 9 additions & 0 deletions src/blsct/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,15 @@ class Common
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0'};

inline static const std::vector<uint8_t> BLSCTFEE = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'B', 'L', 'S', 'C', 'T', 'F', 'E', 'E', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'0', '0', '0', '0', '0', '0', '0', '0'};

static std::vector<uint8_t> DataStreamToVector(const DataStream& st);

/**
Expand Down
16 changes: 16 additions & 0 deletions src/blsct/eip_2333/bls12_381_keygen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,3 +183,19 @@ MclScalar BLS12_381_KeyGen::derive_child_SK(const MclScalar& parent_SK, const ui
auto SK = HKDF_mod_r(std::vector<uint8_t>(comp_PK.cbegin(), comp_PK.cend()));
return SK;
}

MclScalar BLS12_381_KeyGen::derive_child_SK_hash(const MclScalar& parent_SK, const uint256& hash)
{
auto ret = parent_SK;
for (auto i = 0; i < 8; i++) {
const uint8_t* pos = hash.begin() + i * 4;
uint32_t index = (uint8_t)(pos[0]) << 24 |
(uint8_t)(pos[1]) << 16 |
(uint8_t)(pos[2]) << 8 |
(uint8_t)(pos[3]);

auto comp_PK = parent_SK_to_lamport_PK(ret, index);
ret = HKDF_mod_r(std::vector<uint8_t>(comp_PK.cbegin(), comp_PK.cend()));
}
return ret;
}
13 changes: 7 additions & 6 deletions src/blsct/eip_2333/bls12_381_keygen.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,28 @@ class BLS12_381_KeyGen
public:
static MclScalar derive_master_SK(const std::vector<uint8_t>& seed);
static MclScalar derive_child_SK(const MclScalar& parent_SK, const uint32_t& index);
static MclScalar derive_child_SK_hash(const MclScalar& parent_SK, const uint256& hash);

#ifndef BOOST_UNIT_TEST
private:
#endif
inline static const uint32_t DigestSize = CSHA256::OUTPUT_SIZE;
inline static const uint32_t NumLamportChunks = 255;

using LamportChunks = std::array<std::array<uint8_t,DigestSize>,NumLamportChunks>;
using LamportChunks = std::array<std::array<uint8_t, DigestSize>, NumLamportChunks>;

static std::array<uint8_t,DigestSize> HKDF_Extract(const std::vector<uint8_t>& salt, const std::vector<uint8_t>& IKM);
static std::array<uint8_t, DigestSize> HKDF_Extract(const std::vector<uint8_t>& salt, const std::vector<uint8_t>& IKM);

template <size_t L>
static std::array<uint8_t,L> HKDF_Expand(const std::array<uint8_t,DigestSize>& PRK, const std::vector<uint8_t>& info);
static std::array<uint8_t, L> HKDF_Expand(const std::array<uint8_t, DigestSize>& PRK, const std::vector<uint8_t>& info);

static std::vector<uint8_t> I2OSP(const MclScalar& x, const size_t& xLen);
static MclScalar OS2IP(const std::array<uint8_t,48ul>& X);
static MclScalar OS2IP(const std::array<uint8_t, 48ul>& X);
static std::vector<uint8_t> flip_bits(const std::vector<uint8_t>& vec);
static LamportChunks bytes_split(const std::array<uint8_t,8160>& octet_string);
static LamportChunks bytes_split(const std::array<uint8_t, 8160>& octet_string);
static MclScalar HKDF_mod_r(const std::vector<uint8_t>& IKM);
static LamportChunks IKM_to_lamport_SK(const std::vector<uint8_t>& IKM, const std::vector<uint8_t>& salt);
static std::array<uint8_t,DigestSize> parent_SK_to_lamport_PK(const MclScalar& parent_SK, const uint32_t& index);
static std::array<uint8_t, DigestSize> parent_SK_to_lamport_PK(const MclScalar& parent_SK, const uint32_t& index);
};

#endif // NAVIO_BLSCT_EIP_2333_BLS12_381_KEYGEN_H
Expand Down
5 changes: 5 additions & 0 deletions src/blsct/private_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ Signature PrivateKey::SignBalance() const
return CoreSign(Common::BLSCTBALANCE);
}

Signature PrivateKey::SignFee() const
{
return CoreSign(Common::BLSCTFEE);
}

Signature PrivateKey::Sign(const uint256& msg) const
{
return Sign(Message(msg.begin(), msg.end()));
Expand Down
1 change: 1 addition & 0 deletions src/blsct/private_key.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class PrivateKey

// Basic scheme
Signature SignBalance() const;
Signature SignFee() const;

// Message augmentation scheme
Signature Sign(const uint256& msg) const;
Expand Down
2 changes: 1 addition & 1 deletion src/blsct/public_keys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ bool PublicKeys::VerifyBatch(const std::vector<PublicKey::Message>& msgs, const
std::vector<std::vector<uint8_t>> aug_msgs;
auto msg = msgs.begin();
for (auto pk = m_pks.begin(), end = m_pks.end(); pk != end; ++pk, ++msg) {
if (*msg == blsct::Common::BLSCTBALANCE && fVerifyTx) {
if ((*msg == blsct::Common::BLSCTBALANCE || *msg == blsct::Common::BLSCTFEE) && fVerifyTx) {
aug_msgs.push_back(*msg);
} else {
aug_msgs.push_back(pk->AugmentMessage(*msg));
Expand Down
88 changes: 88 additions & 0 deletions src/blsct/tokens/info.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright (c) 2024 The Navio developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef NAVIO_BLSCT_TOKENS_INFO_H
#define NAVIO_BLSCT_TOKENS_INFO_H

#include <blsct/public_key.h>
#include <consensus/amount.h>
#include <tinyformat.h>
#include <util/moneystr.h>

namespace blsct {
enum TokenType : unsigned char {
TOKEN = 0,
NFT = 1
};
std::string TokenTypeToString(const TokenType& type)
{
switch (type) {
case TOKEN: {
return "token";
}
case NFT: {
return "nft";
}
default:
return "unknown";
}
}
class TokenInfo
{
public:
TokenType type;
blsct::PublicKey publicKey;
std::map<std::string, std::string> mapMetadata;
CAmount nTotalSupply;

TokenInfo(const TokenType& type, const blsct::PublicKey& publicKey, const std::map<std::string, std::string>& mapMetadata,
const CAmount& nTotalSupply) : type(type), publicKey(publicKey), mapMetadata(mapMetadata), nTotalSupply(nTotalSupply){};
TokenInfo(){};

SERIALIZE_METHODS(TokenInfo, obj) { READWRITE(static_cast<unsigned char>(obj.type), obj.publicKey, obj.mapMetadata, obj.nTotalSupply); };

std::string ToString() const
{
std::string ret = strprintf("type=%s publicKey=%s", TokenTypeToString(type), publicKey.ToString());
for (auto& it : mapMetadata) {
ret += strprintf(" %s=%s", it.first, it.second);
}
ret += strprintf(" nTotalSupply=%s", FormatMoney(nTotalSupply));
return ret;
}
};

class TokenEntry
{
public:
TokenInfo info;
CAmount nSupply;
std::map<CAmount, std::map<std::string, std::string>> mapMintedNft;

TokenEntry(){};
TokenEntry(const TokenInfo& info,
const CAmount& nSupply = 0) : info(info), nSupply(nSupply){};
TokenEntry(const TokenInfo& info,
const std::map<CAmount, std::map<std::string, std::string>>& mapMintedNft) : info(info), mapMintedNft(mapMintedNft){};

bool Mint(const CAmount& amount)
{
if (amount + nSupply > info.nTotalSupply)
return false;
nSupply += nSupply;
return true;
};

SERIALIZE_METHODS(TokenEntry, obj)
{
READWRITE(obj.info);
if (obj.info.type == TOKEN)
READWRITE(obj.nSupply);
else if (obj.info.type == NFT)
READWRITE(obj.mapMintedNft);
};
};
} // namespace blsct

#endif // NAVIO_BLSCT_TOKENS_INFO_H
12 changes: 12 additions & 0 deletions src/blsct/tokens/predicate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) 2024 The Navio developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef NAVIO_BLSCT_TOKENS_PREDICATE_H
#define NAVIO_BLSCT_TOKENS_PREDICATE_H

namespace blsct {
typedef std::vector<std::byte> VectorPredicate;
}

#endif // NAVIO_BLSCT_TOKENS_PREDICATE_H
95 changes: 95 additions & 0 deletions src/blsct/tokens/predicate_parser.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// Copyright (c) 2024 The Navio developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <blsct/tokens/predicate_parser.h>

namespace blsct {
ParsedPredicate ParsePredicate(const VectorPredicate& vch)
{
DataStream ss{vch};
PredicateOperation op;
ss >> Using<CustomUintFormatter<1>>(op);

if (op == CREATE_TOKEN) {
CreateTokenPredicate p;
ss >> p;
return p;
} else if (op == MINT) {
MintTokenPredicate p;
ss >> p;
return p;
} else if (op == NFT_MINT) {
MintNftPredicate p;
ss >> p;
return p;
} else if (op == PAY_FEE) {
PayFeePredicate p;
ss >> p;
return p;
} else {
throw std::ios_base::failure("unknown predicate operation");
}
}

bool ExecutePredicate(const ParsedPredicate& predicate, CCoinsViewCache& view, const bool& fDisconnect)
{
if (predicate.IsCreateTokenPredicate()) {
auto hash = predicate.GetPublicKey().GetHash();

if (!fDisconnect && view.HaveToken(hash)) return false;

if (fDisconnect)
view.EraseToken(hash);
else
view.AddToken(hash, std::move(predicate.GetTokenInfo()));

return true;
} else if (predicate.IsMintTokenPredicate()) {
auto hash = predicate.GetPublicKey().GetHash();

if (!view.HaveToken(hash))
return false;

blsct::TokenEntry token;

if (!view.GetToken(hash, token))
return false;

if (!token.Mint(predicate.GetAmount() * (1 - 2 * fDisconnect)))
return false;

view.AddToken(hash, std::move(token));

return true;
} else if (predicate.IsMintNftPredicate()) {
auto hash = predicate.GetPublicKey().GetHash();

if (!view.HaveToken(hash))
return false;

blsct::TokenEntry token;

if (!view.GetToken(hash, token))
return false;

if (token.mapMintedNft.contains(predicate.GetNftId()) == !fDisconnect)
return false;

token.mapMintedNft[predicate.GetNftId()] = predicate.GetNftMetaData();

view.AddToken(hash, std::move(token));

return true;
} else if (predicate.IsPayFeePredicate()) {
return true;
}

return false;
}

bool ExecutePredicate(const VectorPredicate& vch, CCoinsViewCache& view, const bool& fDisconnect)
{
return ExecutePredicate(ParsePredicate(vch), view, fDisconnect);
}
} // namespace blsct
Loading

0 comments on commit dce6216

Please sign in to comment.