Skip to content
GitLab
Menu
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
hive
hive-net
Commits
1143b556
Commit
1143b556
authored
Oct 13, 2021
by
Arcange
Browse files
Broadcast transactions implemented
parent
8dd9ad67
Changes
28
Expand all
Hide whitespace changes
Inline
Side-by-side
HiveAPI.CS/CBase58.cs
0 → 100644
View file @
1143b556
using
System
;
using
System.Linq
;
using
System.Text
;
using
System.Text.RegularExpressions
;
using
Cryptography.ECDSA
;
namespace
HiveAPI.CS
{
public
class
CBase58
:
Cryptography
.
ECDSA
.
Base58
{
public
static
byte
[]
DecodePrivateWif
(
string
data
)
{
if
(
data
.
All
(
Hexdigits
.
Contains
))
return
Hex
.
HexToBytes
(
data
);
switch
(
data
[
0
])
{
case
'5'
:
case
'6'
:
return
Base58CheckDecode
(
data
);
case
'K'
:
case
'L'
:
return
CutLastBytes
(
Base58CheckDecode
(
data
),
1
);
default
:
throw
new
NotImplementedException
();
}
}
public
static
string
EncodePrivateWif
(
byte
[]
source
)
{
return
Base58CheckEncode
(
0x80
,
source
);
}
public
static
byte
[]
DecodePublicWif
(
string
publicKey
,
string
prefix
)
{
if
(!
publicKey
.
StartsWith
(
prefix
))
return
new
byte
[
0
];
var
buf
=
publicKey
.
Remove
(
0
,
prefix
.
Length
);
var
s
=
Decode
(
buf
);
var
checksum
=
BitConverter
.
ToInt32
(
s
,
s
.
Length
-
CheckSumSizeInBytes
);
var
dec
=
RemoveCheckSum
(
s
);
var
hash
=
Ripemd160Manager
.
GetHash
(
dec
);
var
newChecksum
=
BitConverter
.
ToInt32
(
hash
,
0
);
if
(
checksum
!=
newChecksum
)
throw
new
ArithmeticException
(
nameof
(
checksum
));
return
dec
;
}
public
static
string
EncodePublicWif
(
byte
[]
publicKey
,
string
prefix
)
{
var
checksum
=
Ripemd160Manager
.
GetHash
(
publicKey
);
var
s
=
AddLastBytes
(
publicKey
,
CheckSumSizeInBytes
);
Array
.
Copy
(
checksum
,
0
,
s
,
s
.
Length
-
CheckSumSizeInBytes
,
CheckSumSizeInBytes
);
var
pubdata
=
Encode
(
s
);
return
prefix
+
pubdata
;
}
public
static
byte
[]
Base58CheckDecode
(
string
data
)
{
var
s
=
Decode
(
data
);
var
dec
=
CutLastBytes
(
s
,
CheckSumSizeInBytes
);
var
checksum
=
DoubleHash
(
dec
);
for
(
var
i
=
0
;
i
<
CheckSumSizeInBytes
;
i
++)
{
if
(
checksum
[
i
]
!=
s
[
s
.
Length
-
CheckSumSizeInBytes
+
i
])
throw
new
ArithmeticException
(
"Invalide data"
);
}
return
CutFirstBytes
(
dec
,
1
);
}
public
static
string
Base58CheckEncode
(
byte
version
,
byte
[]
data
)
{
var
s
=
AddFirstBytes
(
data
,
1
);
s
[
0
]
=
version
;
var
checksum
=
DoubleHash
(
s
);
s
=
AddLastBytes
(
s
,
CheckSumSizeInBytes
);
Array
.
Copy
(
checksum
,
0
,
s
,
s
.
Length
-
CheckSumSizeInBytes
,
CheckSumSizeInBytes
);
return
Encode
(
s
);
}
public
static
string
GetSubWif
(
string
name
,
string
password
,
string
role
)
{
var
seed
=
name
+
role
+
password
;
seed
=
Regex
.
Replace
(
seed
,
@"\s+"
,
" "
);
var
brainKey
=
Encoding
.
ASCII
.
GetBytes
(
seed
);
var
hashSha256
=
Sha256Manager
.
GetHash
(
brainKey
);
return
EncodePrivateWif
(
hashSha256
);
}
}
}
HiveAPI.CS/CHiveAPI.cs
View file @
1143b556
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.Net.Http
;
using
System.Threading.Tasks
;
using
Newtonsoft.Json
;
...
...
@@ -8,7 +7,7 @@ using Newtonsoft.Json.Linq;
namespace
HiveAPI.CS
{
class
CHiveAPI
public
class
CHiveAPI
{
#
region
Constants
const
string
STR_RESULT
=
"result"
;
...
...
@@ -63,54 +62,18 @@ namespace HiveAPI.CS
return
t
.
Result
;
}
}
private
object
ProcessResult
(
Dictionary
<
string
,
JObject
>
oDic
)
{
if
(
oDic
[
STR_RESULT
]
!=
null
)
{
return
oDic
[
STR_RESULT
];
}
if
(
oDic
[
STR_ERROR
]
!=
null
)
{
throw
new
Exception
((
string
)
oDic
[
STR_ERROR
]);
}
throw
new
Exception
(
STR_FORMAT
);
}
private
object
ProcessResult
(
Dictionary
<
string
,
JArray
>
oDic
)
{
if
(
oDic
[
STR_RESULT
]
!=
null
)
{
return
oDic
[
STR_RESULT
];
}
if
(
oDic
[
STR_ERROR
]
!=
null
)
{
throw
new
Exception
((
string
)
oDic
[
STR_ERROR
]);
}
throw
new
Exception
(
STR_FORMAT
);
}
private
object
ProcessResult
(
Dictionary
<
string
,
JToken
>
oDic
)
{
if
(
oDic
[
STR_RESULT
]
!=
null
)
{
return
oDic
[
STR_RESULT
];
}
if
(
oDic
[
STR_ERROR
]
!=
null
)
{
throw
new
Exception
((
string
)
oDic
[
STR_ERROR
]);
}
throw
new
Exception
(
STR_FORMAT
);
}
private
object
ProcessResult
(
Dictionary
<
string
,
JValue
>
oDic
)
{
if
(
oDic
[
STR_RESULT
]
!=
null
)
{
return
oDic
[
STR_RESULT
];
}
if
(
oDic
[
STR_ERROR
]
!=
null
)
{
throw
new
Exception
((
string
)
oDic
[
STR_ERROR
]);
}
throw
new
Exception
(
STR_FORMAT
);
}
private
object
ProcessResult
(
JObject
obj
)
{
if
(
obj
[
STR_RESULT
]
!=
null
)
{
return
obj
[
STR_RESULT
];
}
if
(
obj
[
STR_ERROR
]
!=
null
)
{
throw
new
Exception
(
obj
[
STR_ERROR
].
ToString
());
}
throw
new
Exception
(
STR_FORMAT
);
}
#
endregion
#
region
protected
methods
...
...
@@ -124,37 +87,35 @@ namespace HiveAPI.CS
}
protected
JObject
call_api
(
string
strMethod
)
{
return
(
JObject
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JObject
>
>
(
SendRequest
(
strMethod
)));
return
(
JObject
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>(
SendRequest
(
strMethod
)));
}
protected
JObject
call_api
(
string
strMethod
,
ArrayList
arrParams
)
{
return
(
JObject
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JObject
>>(
SendRequest
(
strMethod
,
arrParams
)));
}
protected
JArray
call_api_array
(
string
strMethod
,
ArrayList
arrParams
)
{
return
(
JArray
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JArray
>>(
SendRequest
(
strMethod
,
arrParams
)));
return
(
JObject
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>(
SendRequest
(
strMethod
,
arrParams
)));
}
protected
JArray
call_api_array
(
string
strMethod
)
protected
JArray
call_api_array
(
string
strMethod
)
{
return
(
JArray
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>(
SendRequest
(
strMethod
)));
}
protected
JArray
call_api_array
(
string
strMethod
,
ArrayList
arrParams
)
{
return
(
JArray
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JArray
>
>(
SendRequest
(
strMethod
)));
return
(
JArray
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>(
SendRequest
(
strMethod
,
arrParams
)));
}
protected
JValue
call_api_value
(
string
strMethod
)
{
return
(
JValue
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JValue
>>(
SendRequest
(
strMethod
)));
return
(
JValue
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>
(
SendRequest
(
strMethod
)));
}
protected
JValue
call_api_value
(
string
strMethod
,
ArrayList
arrParams
)
{
return
(
JValue
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JValue
>>(
SendRequest
(
strMethod
,
arrParams
)));
return
(
JValue
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>(
SendRequest
(
strMethod
,
arrParams
)));
}
protected
JToken
call_api_token
(
string
strMethod
,
ArrayList
arrParams
)
{
return
(
JToken
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JToken
>
>(
SendRequest
(
strMethod
,
arrParams
)));
return
(
JToken
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>(
SendRequest
(
strMethod
,
arrParams
)));
}
protected
JToken
call_api_token
(
string
strMethod
)
{
return
(
JToken
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
Dictionary
<
string
,
JToken
>>
(
SendRequest
(
strMethod
)));
return
(
JToken
)
ProcessResult
(
JsonConvert
.
DeserializeObject
<
JObject
>
(
SendRequest
(
strMethod
)));
}
#
endregion
}
...
...
HiveAPI.CS/CHiveWallet.cs
View file @
1143b556
...
...
@@ -780,9 +780,9 @@ namespace HiveAPI.CS
return
call_api
(
MethodBase
.
GetCurrentMethod
().
Name
,
arrParams
);
}
// Transfers into savings happen immediately
, transfers from savings take 72 hours
// Transfers into savings happen immediately
//
public
JObject
transfer_to_savings
(
string
from
,
string
to
,
string
amount
,
string
memo
,
bool
broadcast
=
fals
e
)
public
JObject
transfer_to_savings
(
string
from
,
string
to
,
string
amount
,
string
memo
,
bool
broadcast
=
tru
e
)
{
ArrayList
arrParams
=
new
ArrayList
();
arrParams
.
Add
(
from
);
...
...
@@ -793,9 +793,10 @@ namespace HiveAPI.CS
}
// @param request_id - an unique ID assigned by from account, the id is used to cancel the operation and can be reused after the transfer completes
// Transfers transfers from savings take 72 hours
// request_id - an unique ID assigned by from account, the id is used to cancel the operation and can be reused after the transfer completes
//
public
JObject
transfer_from_savings
(
string
from
,
UInt32
request_id
,
string
to
,
string
amount
,
string
memo
,
bool
broadcast
=
fals
e
)
public
JObject
transfer_from_savings
(
string
from
,
UInt32
request_id
,
string
to
,
string
amount
,
string
memo
,
bool
broadcast
=
tru
e
)
{
ArrayList
arrParams
=
new
ArrayList
();
arrParams
.
Add
(
from
);
...
...
@@ -806,10 +807,10 @@ namespace HiveAPI.CS
return
call_api
(
MethodBase
.
GetCurrentMethod
().
Name
,
arrParams
);
}
// @param request_id the id used in transfer_from_savings
// @param from the account that initiated the transfer
// @param request_id the id used in transfer_from_savings
//
public
JObject
cancel_transfer_from_savings
(
string
from
,
UInt32
request_id
,
bool
broadcast
=
fals
e
)
public
JObject
cancel_transfer_from_savings
(
string
from
,
UInt32
request_id
,
bool
broadcast
=
tru
e
)
{
ArrayList
arrParams
=
new
ArrayList
();
arrParams
.
Add
(
from
);
...
...
HiveAPI.CS/CHived.cs
View file @
1143b556
using
System
;
using
System.Collections
;
using
System.Collections.Generic
;
using
System.IO
;
using
System.Net.Http
;
using
System.Reflection
;
using
Cryptography.ECDSA
;
using
Newtonsoft.Json.Linq
;
namespace
HiveAPI.CS
{
class
CHived
:
CHiveAPI
public
class
CHived
:
CHiveAPI
{
#
region
Constants
const
string
DATABASE_API
=
"database_api."
;
...
...
@@ -15,6 +17,8 @@ namespace HiveAPI.CS
const
string
BLOCK_API
=
"block_api."
;
const
string
CONDENSER_API
=
"condenser_api."
;
const
string
HIVE_API
=
"hive."
;
const
string
CHAINID
=
"beeab0de00000000000000000000000000000000000000000000000000000000"
;
#
endregion
#
region
Constructors
...
...
@@ -23,7 +27,73 @@ namespace HiveAPI.CS
}
#
endregion
#
region
Public
Methods
#
region
private
Methods
private
class
CTransaction
{
public
UInt16
ref_block_num
;
public
UInt32
ref_block_prefix
;
public
DateTime
expiration
;
public
Object
[]
operations
;
public
Object
[]
extensions
=
{
};
public
string
[]
signatures
=
{
};
}
private
class
CtransactionData
{
public
CTransaction
tx
;
public
string
txid
;
}
private
CtransactionData
SignTransaction
(
CTransaction
oTransaction
,
String
[]
astrPrivateKeys
)
{
CSerializer
oSerializer
=
new
CSerializer
();
byte
[]
msg
=
oSerializer
.
Serialize
(
oTransaction
);
using
(
MemoryStream
oStream
=
new
MemoryStream
())
{
byte
[]
oChainID
=
Hex
.
HexToBytes
(
CHAINID
);
oStream
.
Write
(
oChainID
,
0
,
oChainID
.
Length
);
oStream
.
Write
(
msg
,
0
,
msg
.
Length
);
byte
[]
oDigest
=
Sha256Manager
.
GetHash
(
oStream
.
ToArray
());
foreach
(
string
key
in
astrPrivateKeys
)
{
Array
.
Resize
(
ref
oTransaction
.
signatures
,
oTransaction
.
signatures
.
Length
+
1
);
oTransaction
.
signatures
[
oTransaction
.
signatures
.
Length
-
1
]
=
Hex
.
ToString
(
Secp256K1Manager
.
SignCompressedCompact
(
oDigest
,
CBase58
.
DecodePrivateWif
(
key
)));
}
}
return
new
CtransactionData
{
tx
=
oTransaction
,
txid
=
Hex
.
ToString
(
Sha256Manager
.
GetHash
(
msg
)).
Substring
(
0
,
40
)
};
}
private
CtransactionData
CreateTransaction
(
Object
[]
aOperations
,
string
[]
astrPrivateKeys
)
{
JObject
oDGP
=
get_dynamic_global_properties
();
CTransaction
oTransaction
=
new
CTransaction
{
ref_block_num
=
Convert
.
ToUInt16
((
UInt32
)
oDGP
[
"head_block_number"
]
&
0xFFFF
),
ref_block_prefix
=
BitConverter
.
ToUInt32
(
Hex
.
HexToBytes
(
oDGP
[
"head_block_id"
].
ToString
()),
4
),
expiration
=
Convert
.
ToDateTime
(
oDGP
[
"time"
]).
AddSeconds
(
30
),
operations
=
aOperations
};
return
SignTransaction
(
oTransaction
,
astrPrivateKeys
);
}
#
endregion
#
region
public
Methods
public
string
broadcast_transaction
(
Object
[]
operations
,
string
[]
keys
)
{
CtransactionData
oTransaction
=
CreateTransaction
(
operations
,
keys
);
for
(
int
i
=
0
;
i
<
oTransaction
.
tx
.
operations
.
Length
;
i
++)
{
object
op
=
oTransaction
.
tx
.
operations
[
i
];
oTransaction
.
tx
.
operations
[
i
]
=
new
Op
{
name
=
op
.
GetType
().
Name
,
payload
=
op
};
}
ArrayList
arrParams
=
new
ArrayList
();
arrParams
.
Add
(
oTransaction
.
tx
);
call_api
(
CONDENSER_API
+
MethodBase
.
GetCurrentMethod
().
Name
,
arrParams
);
return
oTransaction
.
txid
;
}
public
JObject
get_info
()
{
return
call_api
(
HIVE_API
+
MethodBase
.
GetCurrentMethod
().
Name
);
...
...
@@ -263,7 +333,7 @@ namespace HiveAPI.CS
//
// from - the absolute sequence number, -1 means most recent, limit Is the number of operations before from.
// limit - the maximum number of items that can be queried (0 to 1000], must be less than from
public
JToken
get_account_history
(
string
account
,
U
Int64
from
,
UInt32
limit
)
public
JToken
get_account_history
(
string
account
,
Int64
from
,
UInt32
limit
)
{
ArrayList
arrParams
=
new
ArrayList
();
arrParams
.
Add
(
account
);
...
...
HiveAPI.CS/COperations.cs
0 → 100644
View file @
1143b556
using
System
;
using
System.Collections.Generic
;
using
System.Globalization
;
using
System.Linq
;
using
Cryptography.ECDSA
;
using
Newtonsoft.Json
;
namespace
HiveAPI.CS
{
[
AttributeUsage
(
AttributeTargets
.
Field
)]
public
class
OptionalField
:
Attribute
{}
public
class
AssetJsonConverter
:
JsonConverter
{
public
override
void
WriteJson
(
JsonWriter
writer
,
Object
value
,
JsonSerializer
serializer
)
{
writer
.
WriteValue
(
value
.
ToString
());
}
public
override
Object
ReadJson
(
JsonReader
reader
,
Type
objectType
,
Object
existingValue
,
JsonSerializer
serializer
)
{
throw
new
NotImplementedException
();
}
public
override
bool
CanConvert
(
Type
objectType
)
{
throw
new
NotImplementedException
();
}
}
[
JsonConverter
(
typeof
(
AssetJsonConverter
))]
public
class
Asset
{
public
decimal
amount
;
public
string
symbol
;
private
string
CheckSymbol
(
string
strSymbol
)
{
string
[]
aSymbols
=
{
"HIVE"
,
"HBD"
,
"TESTS"
,
"TBD"
,
"VESTS"
};
if
(
string
.
IsNullOrEmpty
(
strSymbol
)
||
!
aSymbols
.
Contains
(
strSymbol
))
{
throw
new
Exception
(
string
.
Format
(
"Invalid asset symbol: {0}"
,
strSymbol
));
}
return
strSymbol
;
}
public
Asset
(
decimal
strAmount
,
string
strSymbol
)
{
amount
=
strAmount
;
symbol
=
CheckSymbol
(
strSymbol
);
}
public
Asset
(
string
str
)
{
string
[]
astr
=
str
.
Split
(
' '
);
if
(
astr
.
Length
<
2
)
{
throw
new
Exception
(
"Invalid asset string"
);
}
if
(
string
.
IsNullOrEmpty
(
astr
[
0
]))
{
throw
new
Exception
(
"Invalid asset amount (null or empty)"
);
}
amount
=
decimal
.
Parse
(
astr
[
0
],
CultureInfo
.
InvariantCulture
);
symbol
=
CheckSymbol
(
astr
[
1
]);
}
public
int
GetPrecision
()
{
string
[]
asymbols
=
{
"HIVE"
,
"HBD"
,
"TESTS"
,
"TBD"
};
return
asymbols
.
Contains
(
symbol
)
?
3
:
6
;
}
public
override
string
ToString
()
{
return
string
.
Format
(
CultureInfo
.
InvariantCulture
,
"{0:0."
+
new
string
(
'0'
,
GetPrecision
())
+
"} {1}"
,
amount
,
symbol
);
}
}
public
class
PublicKeyJsonConverter
:
JsonConverter
{
public
override
void
WriteJson
(
JsonWriter
writer
,
Object
value
,
JsonSerializer
serializer
)
{
writer
.
WriteValue
(
value
.
ToString
());
}
public
override
Object
ReadJson
(
JsonReader
reader
,
Type
objectType
,
Object
existingValue
,
JsonSerializer
serializer
)
{
return
new
PublicKey
((
string
)
reader
.
Value
);
}
public
override
bool
CanConvert
(
Type
objectType
)
{
throw
new
NotImplementedException
();
}
}
[
JsonConverter
(
typeof
(
PublicKeyJsonConverter
))]
public
class
PublicKey
{
public
string
key
;
public
PublicKey
(
string
strKey
)
{
key
=
strKey
;
}
public
override
string
ToString
()
{
return
key
;
}
public
Byte
[]
Decode
()
{
return
Base58
.
RemoveCheckSum
(
Base58
.
Decode
(
key
.
Substring
(
3
)));
}
}
public
class
Price
{
public
Asset
@base
;
public
Asset
quote
;
}
public
class
AccountAuthsJsonConverter
:
JsonConverter
{
public
override
void
WriteJson
(
JsonWriter
writer
,
Object
value
,
JsonSerializer
serializer
)
{
Dictionary
<
string
,
UInt16
>
auths
=
(
Dictionary
<
string
,
UInt16
>)
value
;
writer
.
WriteStartArray
();
foreach
(
KeyValuePair
<
string
,
UInt16
>
auth
in
auths
)
{
writer
.
WriteStartArray
();
writer
.
WriteValue
(
auth
.
Key
);
writer
.
WriteValue
(
auth
.
Value
);
writer
.
WriteEndArray
();
}
writer
.
WriteEndArray
();
}
public
override
Object
ReadJson
(
JsonReader
reader
,
Type
objectType
,
Object
existingValue
,
JsonSerializer
serializer
)
{
return
new
PublicKey
((
string
)
reader
.
Value
);
}
public
override
bool
CanConvert
(
Type
objectType
)
{
throw
new
NotImplementedException
();
}
}
public
class
KeyAuthsJsonConverter
:
JsonConverter
{
public
override
void
WriteJson
(
JsonWriter
writer
,
Object
value
,
JsonSerializer
serializer
)
{
Dictionary
<
PublicKey
,
UInt16
>
auths
=
(
Dictionary
<
PublicKey
,
UInt16
>)
value
;
writer
.
WriteStartArray
();
foreach
(
KeyValuePair
<
PublicKey
,
UInt16
>
auth
in
auths
)
{
writer
.
WriteStartArray
();
writer
.
WriteValue
(
auth
.
Key
.
ToString
());
writer
.
WriteValue
(
auth
.
Value
);
writer
.
WriteEndArray
();
}
writer
.
WriteEndArray
();
}
public
override
Object
ReadJson
(
JsonReader
reader
,
Type
objectType
,
Object
existingValue
,
JsonSerializer
serializer
)
{
return
new
PublicKey
((
string
)
reader
.
Value
);
}
public
override
bool
CanConvert
(
Type
objectType
)
{
throw
new
NotImplementedException
();
}
}
public
class
Authority
{
public
UInt32
weight_threshold
;
[
JsonConverter
(
typeof
(
AccountAuthsJsonConverter
))]
public
Dictionary
<
string
,
UInt16
>
account_auths
=
new
Dictionary
<
string
,
UInt16
>();
[
JsonConverter
(
typeof
(
KeyAuthsJsonConverter
))]
public
Dictionary
<
PublicKey
,
UInt16
>
key_auths
=
new
Dictionary
<
PublicKey
,
UInt16
>();
}
public
class
ChainProperties
{
public
Asset
account_creation_fee
;
public
UInt32
maximum_block_size
;
public
UInt16
hbd_interest_rate
;
}
public
class
WitnessProperties
{
public
Asset
account_creation_fee
;
public
UInt32
account_voidsidy_budget
;
public
UInt32
account_voidsidy_decay
;
public
UInt32
maximum_block_size
;
public
UInt16
hbd_interest_rate
;
public
Price
hbd_exchange_rate
;
public
string
url
;
public
PublicKey
new_signing_key
;
}
public
class
OpJsonConverter
:
JsonConverter
{
public
override
bool
CanConvert
(
Type
objectType
)
{
throw
new
NotImplementedException
();
}
public
override
object
ReadJson
(
JsonReader
reader
,
Type
objectType
,
object
existingValue
,
JsonSerializer
serializer
)
{
throw
new
NotImplementedException
();
}
public
override
void
WriteJson
(
JsonWriter
writer
,
object
value
,
JsonSerializer
serializer
)
{
Op
op
=
(
Op
)
value
;
writer
.
WriteStartArray
();
writer
.
WriteValue
(
op
.
name
);
serializer
.
Serialize
(
writer
,
op
.
payload
);
writer
.
WriteEndArray
();
}
}
[
JsonConverter
(
typeof
(
OpJsonConverter
))]
public
class
Op
{
public
string
name
;
public
object
payload
;
}
public
class
COperations
{
public
interface
IOperationID
{
int
opid
{
get
;
}
}
public
class
vote
:
IOperationID
{
public
int
opid
=>
0
;
public
string
voter
;
public
string
author
;
public
string
permlink
;
public
Int16