Skip to content

Commit 612cd70

Browse files
docs(fdc): update FDC interfaces w/ Solidity best practices (#950)
2 parents d06cf91 + 5d98071 commit 612cd70

19 files changed

+615
-642
lines changed

docs/fdc/reference/IAddressValidity.mdx

Lines changed: 8 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ sidebar_position: 6
44
description: Assert whether a string represents a valid address.
55
---
66

7+
import CodeBlock from "@theme/CodeBlock";
8+
import AddressVerifier from "!!raw-loader!/examples/developer-hub-solidity/AddressVerifier.sol";
9+
import Remix from "@site/src/components/remix";
10+
711
Assert whether a string represents a valid address on an external blockchain.
812

913
Sourced from `IAddressValidity.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IAddressValidity.sol).
@@ -142,62 +146,7 @@ struct ResponseBody {
142146

143147
## Usage Example
144148

145-
```solidity
146-
// SPDX-License-Identifier: MIT
147-
pragma solidity ^0.8.0;
148-
149-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
150-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
151-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IAddressValidity.sol";
152-
153-
contract AddressVerifier {
154-
IFdcHub private fdcHub;
155-
IFdcVerification private fdcVerification;
156-
157-
bytes32 private constant ATTESTATION_TYPE_ADDRESS_VALIDITY = 0x0500000000000000000000000000000000000000000000000000000000000000;
158-
bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
159-
160-
constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
161-
fdcHub = IFdcHub(_fdcHubAddress);
162-
fdcVerification = IFdcVerification(_fdcVerificationAddress);
163-
}
164-
165-
// Request address validation
166-
function requestAddressValidation(string calldata _address) external payable {
167-
// Create request body
168-
IAddressValidity.RequestBody memory requestBody = IAddressValidity.RequestBody({
169-
addressStr: _address
170-
});
171-
172-
// Encode the full request
173-
bytes memory encodedRequest = abi.encode(
174-
ATTESTATION_TYPE_ADDRESS_VALIDITY,
175-
SOURCE_ID_BTC,
176-
bytes32(0), // messageIntegrityCode (would need to be calculated properly)
177-
requestBody
178-
);
179-
180-
// Submit the request with payment
181-
fdcHub.requestAttestation{value: msg.value}(encodedRequest);
182-
}
183-
184-
// Verify a provided proof
185-
function verifyAddressProof(IAddressValidity.Proof calldata _proof) external view returns (
186-
bool isValid,
187-
string memory standardAddress,
188-
bytes32 standardAddressHash
189-
) {
190-
// Verify the proof using FdcVerification
191-
bool proofVerified = fdcVerification.verifyAddressValidity(_proof);
192-
193-
if (proofVerified) {
194-
// Extract data from the verified proof
195-
isValid = _proof.data.responseBody.isValid;
196-
standardAddress = _proof.data.responseBody.standardAddress;
197-
standardAddressHash = _proof.data.responseBody.standardAddressHash;
198-
}
199-
200-
return (isValid, standardAddress, standardAddressHash);
201-
}
202-
}
203-
```
149+
<CodeBlock language="solidity" title="AddressVerifier.sol">
150+
{AddressVerifier}
151+
</CodeBlock>
152+
<Remix fileName="AddressVerifier.sol">Open example in Remix</Remix>

docs/fdc/reference/IBalanceDecreasingTransaction.mdx

Lines changed: 8 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ sidebar_position: 7
44
description: Detect a transaction that decreases an address balance.
55
---
66

7+
import CodeBlock from "@theme/CodeBlock";
8+
import LockMonitor from "!!raw-loader!/examples/developer-hub-solidity/LockMonitor.sol";
9+
import Remix from "@site/src/components/remix";
10+
711
An interface to detect transactions that decrease the balance of a specific address or are signed by that address on external blockchains.
812

913
Sourced from `IBalanceDecreasingTransaction.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IBalanceDecreasingTransaction.sol).
@@ -239,75 +243,7 @@ Response body containing details about the balance decreasing transaction.
239243

240244
## Usage Example
241245

242-
```solidity
243-
// SPDX-License-Identifier: MIT
244-
pragma solidity ^0.8.0;
245-
246-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
247-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
248-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IBalanceDecreasingTransaction.sol";
249-
250-
contract LockMonitor {
251-
IFdcHub private fdcHub;
252-
IFdcVerification private fdcVerification;
253-
254-
bytes32 private constant ATTESTATION_TYPE_BALANCE_DECREASING = 0x0200000000000000000000000000000000000000000000000000000000000000;
255-
bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
256-
257-
mapping(bytes32 => bool) public lockedAddresses; // sourceAddressHash => isLocked
258-
259-
constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
260-
fdcHub = IFdcHub(_fdcHubAddress);
261-
fdcVerification = IFdcVerification(_fdcVerificationAddress);
262-
}
263-
264-
// Register an address as locked (should not spend funds)
265-
function registerLockedAddress(bytes32 sourceAddressHash) external {
266-
lockedAddresses[sourceAddressHash] = true;
267-
}
268-
269-
// Request verification of a transaction that might violate lock agreement
270-
function checkViolation(bytes32 transactionId, bytes32 sourceAddressIndicator) external payable {
271-
// Create request body
272-
IBalanceDecreasingTransaction.RequestBody memory requestBody = IBalanceDecreasingTransaction.RequestBody({
273-
transactionId: transactionId,
274-
sourceAddressIndicator: sourceAddressIndicator
275-
});
276-
277-
// Encode the full request
278-
bytes memory encodedRequest = abi.encode(
279-
ATTESTATION_TYPE_BALANCE_DECREASING,
280-
SOURCE_ID_BTC,
281-
bytes32(0), // messageIntegrityCode (would need to be calculated properly)
282-
requestBody
283-
);
284-
285-
// Submit the request with payment
286-
fdcHub.requestAttestation{value: msg.value}(encodedRequest);
287-
}
288-
289-
// Verify a provided proof and take action if a locked address has spent funds
290-
function verifyViolation(IBalanceDecreasingTransaction.Proof calldata _proof)
291-
external
292-
returns (bool isViolation)
293-
{
294-
// Verify the proof using FdcVerification
295-
bool proofVerified = fdcVerification.verifyBalanceDecreasingTransaction(_proof);
296-
297-
if (proofVerified) {
298-
// Extract the sourceAddressHash
299-
bytes32 sourceAddressHash = _proof.data.responseBody.sourceAddressHash;
300-
int256 spentAmount = _proof.data.responseBody.spentAmount;
301-
302-
// Check if this is a locked address and the amount spent is positive
303-
if (lockedAddresses[sourceAddressHash] && spentAmount > 0) {
304-
// Take action - e.g., liquidate collateral, notify stakeholders, etc.
305-
lockedAddresses[sourceAddressHash] = false; // Remove from locked addresses
306-
return true;
307-
}
308-
}
309-
310-
return false;
311-
}
312-
}
313-
```
246+
<CodeBlock language="solidity" title="LockMonitor.sol">
247+
{LockMonitor}
248+
</CodeBlock>
249+
<Remix fileName="LockMonitor.sol">Open example in Remix</Remix>

docs/fdc/reference/IConfirmedBlockHeightExists.mdx

Lines changed: 8 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ sidebar_position: 8
44
description: Assert that a block number is confirmed.
55
---
66

7+
import CodeBlock from "@theme/CodeBlock";
8+
import BlockchainMonitor from "!!raw-loader!/examples/developer-hub-solidity/BlockchainMonitor.sol";
9+
import Remix from "@site/src/components/remix";
10+
711
An interface to verify that a specified block has been confirmed on an external blockchain and to calculate block production rates.
812

913
Sourced from `IConfirmedBlockHeightExists.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IConfirmedBlockHeightExists.sol).
@@ -207,79 +211,10 @@ average_block_time = time_elapsed / blocks_produced
207211

208212
## Usage Example
209213

210-
```solidity
211-
// SPDX-License-Identifier: MIT
212-
pragma solidity ^0.8.0;
213-
214-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
215-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
216-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IConfirmedBlockHeightExists.sol";
217-
218-
contract BlockchainMonitor {
219-
IFdcHub private fdcHub;
220-
IFdcVerification private fdcVerification;
221-
222-
bytes32 private constant ATTESTATION_TYPE_CONFIRMED_BLOCK = 0x0200000000000000000000000000000000000000000000000000000000000000;
223-
bytes32 private constant SOURCE_ID_BTC = 0x4254430000000000000000000000000000000000000000000000000000000000;
224-
225-
constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
226-
fdcHub = IFdcHub(_fdcHubAddress);
227-
fdcVerification = IFdcVerification(_fdcVerificationAddress);
228-
}
229-
230-
// Request confirmation of a block
231-
function requestBlockConfirmation(uint64 blockNumber, uint64 queryWindow) external payable {
232-
// Create request body
233-
IConfirmedBlockHeightExists.RequestBody memory requestBody = IConfirmedBlockHeightExists.RequestBody({
234-
blockNumber: blockNumber,
235-
queryWindow: queryWindow
236-
});
237-
238-
// Encode the full request
239-
bytes memory encodedRequest = abi.encode(
240-
ATTESTATION_TYPE_CONFIRMED_BLOCK,
241-
SOURCE_ID_BTC,
242-
bytes32(0), // messageIntegrityCode (would need to be calculated properly)
243-
requestBody
244-
);
245-
246-
// Submit the request with payment
247-
fdcHub.requestAttestation{value: msg.value}(encodedRequest);
248-
}
249-
250-
// Verify a provided proof and calculate block rate
251-
function verifyBlockAndCalculateRate(IConfirmedBlockHeightExists.Proof calldata _proof)
252-
external view
253-
returns (
254-
bool blockConfirmed,
255-
uint64 avgBlockTimeSeconds
256-
)
257-
{
258-
// Verify the proof using FdcVerification
259-
bool proofVerified = fdcVerification.verifyConfirmedBlockHeightExists(_proof);
260-
261-
if (proofVerified) {
262-
// Extract data for calculation
263-
uint64 blockNumber = _proof.data.requestBody.blockNumber;
264-
uint64 blockTimestamp = _proof.data.responseBody.blockTimestamp;
265-
uint64 lowestNumber = _proof.data.responseBody.lowestQueryWindowBlockNumber;
266-
uint64 lowestTimestamp = _proof.data.responseBody.lowestQueryWindowBlockTimestamp;
267-
268-
// Calculate average block time
269-
uint64 blocksProduced = blockNumber - lowestNumber;
270-
uint64 timeElapsed = blockTimestamp - lowestTimestamp;
271-
272-
if (blocksProduced > 0) {
273-
avgBlockTimeSeconds = timeElapsed / blocksProduced;
274-
}
275-
276-
return (true, avgBlockTimeSeconds);
277-
}
278-
279-
return (false, 0);
280-
}
281-
}
282-
```
214+
<CodeBlock language="solidity" title="BlockchainMonitor.sol">
215+
{BlockchainMonitor}
216+
</CodeBlock>
217+
<Remix fileName="BlockchainMonitor.sol">Open example in Remix</Remix>
283218

284219
## Related Interfaces
285220

docs/fdc/reference/IEVMTransaction.mdx

Lines changed: 8 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ sidebar_position: 9
44
description: Relay a transaction from an EVM chain.
55
---
66

7+
import CodeBlock from "@theme/CodeBlock";
8+
import EVMTransactionVerifier from "!!raw-loader!/examples/developer-hub-solidity/EVMTransactionVerifier.sol";
9+
import Remix from "@site/src/components/remix";
10+
711
An interface to relay and verify transactions from EVM-compatible blockchains.
812

913
Sourced from `IEVMTransaction.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IEVMTransaction.sol).
@@ -251,99 +255,7 @@ When working with events, it's important to remember:
251255

252256
## Usage Example
253257

254-
```solidity
255-
// SPDX-License-Identifier: MIT
256-
pragma solidity ^0.8.0;
257-
258-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcHub.sol";
259-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/IFdcVerification.sol";
260-
import "@flare-foundation/flare-smart-contracts-v2/contracts/userInterfaces/fdc/IEVMTransaction.sol";
261-
262-
contract EVMTransactionVerifier {
263-
IFdcHub private fdcHub;
264-
IFdcVerification private fdcVerification;
265-
266-
bytes32 private constant ATTESTATION_TYPE_EVM_TX = 0x0600000000000000000000000000000000000000000000000000000000000000;
267-
bytes32 private constant SOURCE_ID_ETH = 0x4554480000000000000000000000000000000000000000000000000000000000;
268-
269-
// Event signatures we're interested in
270-
bytes32 private constant EVENT_TRANSFER = 0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;
271-
272-
constructor(address _fdcHubAddress, address _fdcVerificationAddress) {
273-
fdcHub = IFdcHub(_fdcHubAddress);
274-
fdcVerification = IFdcVerification(_fdcVerificationAddress);
275-
}
276-
277-
// Request verification of an EVM transaction with specific events
278-
function requestTransactionVerification(
279-
bytes32 transactionHash,
280-
uint16 requiredConfirmations,
281-
bool includeInput,
282-
uint32[] calldata eventIndices
283-
) external payable {
284-
// Create request body
285-
IEVMTransaction.RequestBody memory requestBody = IEVMTransaction.RequestBody({
286-
transactionHash: transactionHash,
287-
requiredConfirmations: requiredConfirmations,
288-
provideInput: includeInput,
289-
listEvents: eventIndices.length > 0,
290-
logIndices: eventIndices
291-
});
292-
293-
// Encode the full request
294-
bytes memory encodedRequest = abi.encode(
295-
ATTESTATION_TYPE_EVM_TX,
296-
SOURCE_ID_ETH,
297-
bytes32(0), // messageIntegrityCode (would need to be calculated properly)
298-
requestBody
299-
);
300-
301-
// Submit the request with payment
302-
fdcHub.requestAttestation{value: msg.value}(encodedRequest);
303-
}
304-
305-
// Verify a provided proof and extract ERC-20 transfer information
306-
function verifyERC20Transfer(IEVMTransaction.Proof calldata _proof)
307-
external view
308-
returns (
309-
bool success,
310-
address tokenContract,
311-
address from,
312-
address to,
313-
uint256 amount
314-
)
315-
{
316-
// Verify the proof using FdcVerification
317-
bool proofVerified = fdcVerification.verifyEVMTransaction(_proof);
318-
319-
if (proofVerified && _proof.data.responseBody.status == 1) {
320-
// Look for Transfer events in the transaction
321-
IEVMTransaction.Event[] memory events = _proof.data.responseBody.events;
322-
323-
for (uint i = 0; i < events.length; i++) {
324-
IEVMTransaction.Event memory evt = events[i];
325-
326-
// Check if this is a Transfer event (topic[0] is the event signature)
327-
if (evt.topics.length >= 3 && evt.topics[0] == EVENT_TRANSFER) {
328-
tokenContract = evt.emitterAddress;
329-
330-
// ERC-20 Transfer(address indexed from, address indexed to, uint256 amount)
331-
// topics[1] is the first indexed parameter (from address)
332-
// topics[2] is the second indexed parameter (to address)
333-
// The addresses are padded to 32 bytes, so we need to extract them
334-
from = address(uint160(uint256(evt.topics[1])));
335-
to = address(uint160(uint256(evt.topics[2])));
336-
337-
// The amount is in the data field for non-indexed parameters
338-
// It's a single uint256 value (32 bytes)
339-
amount = abi.decode(evt.data, (uint256));
340-
341-
return (true, tokenContract, from, to, amount);
342-
}
343-
}
344-
}
345-
346-
return (false, address(0), address(0), address(0), 0);
347-
}
348-
}
349-
```
258+
<CodeBlock language="solidity" title="EVMTransactionVerifier.sol">
259+
{EVMTransactionVerifier.toString()}
260+
</CodeBlock>
261+
<Remix fileName="EVMTransactionVerifier.sol">Open example in Remix</Remix>

0 commit comments

Comments
 (0)