Naming Convention Conflict Between FunC and Tact – Impacts Jetton Compatibility
arghaffari opened this issue · comments
In FunC, we typically use snake_case, whereas in Tact, I've noticed a preference for camelCase. This isn't a problem most of the time, but it becomes critical when we're working with standard patterns like getter functions.
For example, the official Tact documentation uses camelCase for getter functions. But if we name the get_jetton_data function as getJettonData (following Tact style), TON viewers won't recognize it as a standard jetton getter, which breaks compatibility.
This leads to a dilemma:
-
Should we stick to Tact's camelCase convention and risk compatibility issues with TON ecosystem tools?
-
Or should we selectively use snake_case for known patterns like standard getters to ensure they are recognized?
What’s the best path forward here?
Would love to hear your thoughts!
2nd is the answer. Whenever there's a standard (like TEPs) that defines some getter functions, all those getter functions must be named the same to preserve compatibility with the said standard, be it snake_case or anything else. For example, we make get_jetton_data() and other getters named in the snake_case style to be compatible with the TEP 74.
That said, if you do not have to conform to a particular standard, you can use the camelCase convention. Furthermore, while the original getter names are preserved in the actual contract's code, in TypeScript wrappers Tact converts getter names to camelCode, such that in your TypeScript code you'll be able to call await contract.getX()
, where X
is the camelCased version of the getter name.
Hope that answers your question :)
An alternative would be to use the explicit method_id
: https://docs.tact-lang.org/book/functions/#explicit-resolution-of-method-id-collisions.

You can explicitly add get(0x1987d)
and it should solve the issue.
Thanks to both of you; the latter is straightforward.
I initially set method IDs get(0x1987d)
for get_wallet_data
and get(0x1b151)
for get_jetton_data
, but the TON viewer wasn't able to display the jetton metadata correctly. Therefore, I rewrote the method_id
converter as follows:
function crc16_xmodem(str) {
const poly = 0x1021;
let crc = 0x0000; // initial value = 0x0000 (important!)
for (let i = 0; i < str.length; i++) {
crc ^= (str.charCodeAt(i) << 8);
for (let j = 0; j < 8; j++) {
crc = (crc & 0x8000) ? ((crc << 1) ^ poly) : (crc << 1);
crc &= 0xFFFF;
}
}
return crc & 0xFFFF;
}
// Example usage:
const funcnames = ["get_jetton_data", "get_wallet_data"];
for (let name of funcnames) {
const crc = crc16_xmodem(name);
const method_id = (crc & 0xffff) | 0x10000;
console.log(`Function: ${name}, CRC16: ${crc.toString(16)}, Method ID: ${method_id.toString(16)}`);
}
The outputs were:
Function: get_jetton_data, CRC16: 9e2d, Method ID: 19e2d
Function: get_wallet_data, CRC16: 7b02, Method ID: 17b02
After deploying these corrected method IDs, the issue was resolved. It seems the lint placeholder might have had problems with conversions.
Hey, @arghaffari, thanks for the report! It was a bug in LS, now LS shows the ID correctly, you can install the version with the fix from here: https://github.com/tact-lang/tact-language-server/releases/tag/nightly
Or you can update the extension to version 0.5.1 :)
Thanks it's got fixed!
@arghaffari Thanks a lot for catching that pesky bug 🚀