rippled
Loading...
Searching...
No Matches
nft.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2023 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_PROTOCOL_NFT_H_INCLUDED
21#define RIPPLE_PROTOCOL_NFT_H_INCLUDED
22
23#include <xrpl/basics/base_uint.h>
24#include <xrpl/basics/tagged_integer.h>
25#include <xrpl/protocol/AccountID.h>
26
27#include <boost/endian/conversion.hpp>
28
29#include <cstdint>
30#include <cstring>
31
32namespace ripple {
33namespace nft {
34
35// Separate taxons from regular integers.
37{
38};
40
41inline Taxon
43{
44 return static_cast<Taxon>(i);
45}
46
47inline std::uint32_t
49{
50 return static_cast<std::uint32_t>(t);
51}
52
53constexpr std::uint16_t const flagBurnable = 0x0001;
54constexpr std::uint16_t const flagOnlyXRP = 0x0002;
55constexpr std::uint16_t const flagCreateTrustLines = 0x0004;
56constexpr std::uint16_t const flagTransferable = 0x0008;
57constexpr std::uint16_t const flagMutable = 0x0010;
58
59inline std::uint16_t
60getFlags(uint256 const& id)
61{
62 std::uint16_t flags;
63 memcpy(&flags, id.begin(), 2);
64 return boost::endian::big_to_native(flags);
65}
66
67inline std::uint16_t
69{
70 std::uint16_t fee;
71 memcpy(&fee, id.begin() + 2, 2);
72 return boost::endian::big_to_native(fee);
73}
74
75inline std::uint32_t
77{
78 std::uint32_t seq;
79 memcpy(&seq, id.begin() + 28, 4);
80 return boost::endian::big_to_native(seq);
81}
82
83inline Taxon
85{
86 // An issuer may issue several NFTs with the same taxon; to ensure that NFTs
87 // are spread across multiple pages we lightly mix the taxon up by using the
88 // sequence (which is not under the issuer's direct control) as the seed for
89 // a simple linear congruential generator.
90 //
91 // From the Hull-Dobell theorem we know that f(x)=(m*x+c) mod n will yield a
92 // permutation of [0, n) when n is a power of 2 if m is congruent to 1 mod 4
93 // and c is odd.
94 //
95 // Here we use m = 384160001 and c = 2459. The modulo is implicit because we
96 // use 2^32 for n and the arithmetic gives it to us for "free".
97 //
98 // Note that the scramble value we calculate is not cryptographically secure
99 // but that's fine since all we're looking for is some dispersion.
100 //
101 // **IMPORTANT** Changing these numbers would be a breaking change requiring
102 // an amendment along with a way to distinguish token IDs that
103 // were generated with the old code.
104 return taxon ^ toTaxon(((384160001 * tokenSeq) + 2459));
105}
106
107inline Taxon
109{
110 std::uint32_t taxon;
111 memcpy(&taxon, id.begin() + 24, 4);
112 taxon = boost::endian::big_to_native(taxon);
113
114 // The taxon cipher is just an XOR, so it is reversible by applying the
115 // XOR a second time.
116 return cipheredTaxon(getSerial(id), toTaxon(taxon));
117}
118
119inline AccountID
121{
122 return AccountID::fromVoid(id.data() + 4);
123}
124
125} // namespace nft
126} // namespace ripple
127
128#endif
static base_uint fromVoid(void const *data)
Definition base_uint.h:319
A type-safe wrap around standard integral types.
constexpr std::uint16_t const flagBurnable
Definition nft.h:53
std::uint16_t getTransferFee(uint256 const &id)
Definition nft.h:68
std::uint16_t getFlags(uint256 const &id)
Definition nft.h:60
std::uint32_t toUInt32(Taxon t)
Definition nft.h:48
Taxon getTaxon(uint256 const &id)
Definition nft.h:108
constexpr std::uint16_t const flagMutable
Definition nft.h:57
AccountID getIssuer(uint256 const &id)
Definition nft.h:120
constexpr std::uint16_t const flagOnlyXRP
Definition nft.h:54
Taxon cipheredTaxon(std::uint32_t tokenSeq, Taxon taxon)
Definition nft.h:84
Taxon toTaxon(std::uint32_t i)
Definition nft.h:42
tagged_integer< std::uint32_t, TaxonTag > Taxon
Definition nft.h:39
constexpr std::uint16_t const flagTransferable
Definition nft.h:56
constexpr std::uint16_t const flagCreateTrustLines
Definition nft.h:55
std::uint32_t getSerial(uint256 const &id)
Definition nft.h:76
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:25